最近在我的大学开始了 ARM 汇编类(class),或者任务是创建一个 NxM * MxP 矩阵乘法程序,该程序从 C 代码调用。
现在我对 assambler 的了解相当有限,但我非常愿意学习。我想知道的是:
- 如何从 C 读取/传递二维数组到 ASM?
- 如何将二维数组输出回 C?
我在想,我可以自己解决剩下的问题,但是这两点是我觉得困难的地方。
我在 qemu 上使用 ARM 程序集,在 Ubuntu 上使用此代码,它不会在任何特定设备上运行。
最佳答案
C 数组只是指针,因此当您将 C 数组作为参数传递给汇编函数时,您将获得一个指向内存区域的指针,该区域是数组的内容。
要检索参数,这取决于您使用的调用约定。 ARM EABI规定:
The first four registers r0-r3 (a1-a4) are used to pass argument values into a subroutine and to return a result value from a function. They may also be used to hold intermediate values within a routine (but, in general, only between subroutine calls).
对于简单的函数,它们,您应该根据您的函数签名在 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]
的含义是“将pc+12
处的内存地址的内容载入r0
”。这就是存储指向数组的指针的位置。
关于c - ARM汇编中的矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16632752/