ARM程序集中的矩阵乘法

时间:2013-05-19 08:30:41

标签: c assembly arm

ARM组装课程最近在我的大学开始,或者分配是创建一个NxM * MxP矩阵乘法程序,从C代码调用。

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

  1. 如何从2D读取/传递2D数组到ASM?
  2. 如何将2D数组输出回C?
  3. 我在想,我可以自己解决剩下的问题,但这两点是我觉得很难的。

    我在qemu上使用ARM程序集,在Ubuntu上使用此代码,它不会在任何特定设备上运行。

2 个答案:

答案 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来查看单参数函数r0ldr 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值,并且因为数组元素的地址没有改变,所以我只使用相同的数组来输出结果。