c - ARM汇编中的矩阵乘法

标签 c assembly arm

最近在我的大学开始了 ARM 汇编类(class),或者任务是创建一个 NxM * MxP 矩阵乘法程序,该程序从 C 代码调用。

现在我对 assambler 的了解相当有限,但我非常愿意学习。我想知道的是:

  1. 如何从 C 读取/传递二维数组到 ASM?
  2. 如何将二维数组输出回 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/

相关文章:

c++ - C++ 或 ANSI C 所用的周期数?

assembly - 为什么我的汇编程序无法运行?

c - 如何从 ARM 汇编调用 C 函数?

android-ndk - 如何检测Android x86何时模拟ARM?

c - 如何打印数组中包含的结构元素

c - 反向打印链表

c - printf 不打印到屏幕

python - 汇编 x86 "PSHUFB 128bit"另一种语言的实现

c - 求 BST 的最大值和最小值

无法使用 IAR ARM 编译器强制函数表到特定地址