ARM组装课程最近在我的大学开始,或者分配是创建一个NxM * MxP矩阵乘法程序,从C代码调用 .
现在我对assambler的知识相当有限,但我更愿意学习 . 我想知道的是:
如何从C读取/传递2D数组到ASM?
如何将2D数组输出回C?
我在想,我可以自己解决剩下的问题,但这两点是我觉得很困难的 .
我在qemu上使用ARM程序集,在Ubuntu上使用此代码,它不会在任何特定设备上运行 .
C数组只是指针,因此当您将C数组作为参数传递给assemply函数时,您将获得指向作为数组内容的内存区域的指针 .
要检索参数,它取决于您使用的调用约定 . ARM EABI规定:
前四个寄存器r0-r3(a1-a4)用于将参数值传递给子程序并从函数返回结果值 . 它们也可用于在例程中保存中间值(但通常仅用于子例程调用之间) .
对于简单的函数,你应该在r0到r4中找到指向数组的指针,具体取决于你的函数签名 . 否则,您将在堆栈中找到它 . 一个很好的技术可以准确地找出ABI的内容,即反汇编调用汇编函数的C代码的目标文件,并在调用Assembly函数之前检查它的作用 .
例如,在Linux上,您可以在名为 testasm.c 的文件中编译以下C代码:
testasm.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
您可以通过将参数放入寄存器 r0 来查看单参数函数 myasmfunc . ldr r0, [pc, #12] 的含义是“加载到 r0 内存地址的内容 pc+12 ” . 这是存储指向数组的指针的地方 .
r0
myasmfunc
ldr r0, [pc, #12]
pc+12
虽然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值,并且因为数组元素的地址没有改变,所以我只使用相同的数组来输出结果 .
malloc
2 回答
C数组只是指针,因此当您将C数组作为参数传递给assemply函数时,您将获得指向作为数组内容的内存区域的指针 .
要检索参数,它取决于您使用的调用约定 . ARM EABI规定:
对于简单的函数,你应该在r0到r4中找到指向数组的指针,具体取决于你的函数签名 . 否则,您将在堆栈中找到它 . 一个很好的技术可以准确地找出ABI的内容,即反汇编调用汇编函数的C代码的目标文件,并在调用Assembly函数之前检查它的作用 .
例如,在Linux上,您可以在名为
testasm.c
的文件中编译以下C代码:然后编译它:
最后得到一个反汇编:
结果是:
您可以通过将参数放入寄存器
r0
来查看单参数函数myasmfunc
.ldr r0, [pc, #12]
的含义是“加载到r0
内存地址的内容pc+12
” . 这是存储指向数组的指针的地方 .虽然Guillaumes的回答帮了我很多,但我只是想用一些代码回答我自己的问题 .
我最终做的是创建一个一维数组,并将其与维度一起传递给asm .
话虽这么说,我分配了另一个数组(
malloc
)的方式,并将其传递给它 . 然后我只是在汇编代码中的相应地址中存储了我需要的int值,并且因为数组元素的地址没有改变,所以我只使用相同的数组来输出结果 .