ARM组装课程最近在我的大学开始,或者分配是创建一个NxM * MxP矩阵乘法程序,从C代码调用。
现在我对assambler的知识相当有限,但我非常愿意学习。我想知道的是:
我在想,我可以自己解决剩下的问题,但这两点是我觉得很难的。
我在qemu上使用ARM程序集,在Ubuntu上使用此代码,它不会在任何特定设备上运行。
答案 0 :(得分:2)
C数组只是指针,因此当您将C数组作为参数传递给assemply函数时,您将获得一个指向作为数组内容的内存区域的指针。
要检索参数,它取决于您使用的调用约定。 ARM EABI规定:
前四个寄存器r0-r3(a1-a4)用于将参数值传递给子程序并返回结果 函数的值。它们也可用于在例程中保存中间值(但通常只用于 在子程序调用之间。)
对于简单函数,它们应该在r0到r4中找到指向数组的指针,具体取决于函数签名。否则,您将在堆栈中找到它。一个很好的技术,可以准确地找出ABI的内容,反汇编调用汇编函数的C代码的目标文件,并在调用汇编函数之前检查它的作用。
例如,在Linux上,您可以在名为testasm.c
的文件中编译以下C代码:
extern int myasmfunc(int *);
static int array[] = { 0, 1, 2 };
int mycfunc()
{
return myasmfunc(array);
}
然后用:
编译它arm-linux-gnueabi-gcc -c testasm.c
最后得到一个反汇编:
arm-linux-gnueabi-objdump -S testasm.o
结果是:
testasm.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <mycfunc>:
0: e92d4800 push {fp, lr}
4: e28db004 add fp, sp, #4
8: e59f000c ldr r0, [pc, #12] ; 1c <mycfunc+0x1c>
c: ebfffffe bl 0 <myasmfunc>
10: e1a03000 mov r3, r0
14: e1a00003 mov r0, r3
18: e8bd8800 pop {fp, pc}
1c: 00000000 andeq r0, r0, r0
您可以通过将参数放入寄存器myasmfunc
来查看单参数函数r0
。 ldr r0, [pc, #12]
的含义是“加载到r0
内存地址的内容pc+12
”。这就是存储指向数组的指针。
答案 1 :(得分:0)
尽管Guillaumes的回答帮了我很多,但我只是想用一些代码回答我自己的问题。
我最终做的是创建一个一维数组,并将其与维度一起传递给asm。
int *p;
scanf("%d", &h1);
scanf("%d", &w1);
int* A =(int *) malloc (sizeof(int) * ( w1 * h1 ));
p=A;
int i;
int j;
for(i=0;i<(w1*h1);i++)
{
scanf("%d", p++);
}
话虽如此,我以相同的(malloc
)方式分配了另一个数组,并将其传递给了它。然后我只是在汇编代码中的相应地址中存储了我需要的int值,并且因为数组元素的地址没有改变,所以我只使用相同的数组来输出结果。