首页 文章

ARM程序集中的矩阵乘法

提问于
浏览
0

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

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

  • 如何从C读取/传递2D数组到ASM?

  • 如何将2D数组输出回C?

我在想,我可以自己解决剩下的问题,但这两点是我觉得很困难的 .

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

2 回答

  • 2

    C数组只是指针,因此当您将C数组作为参数传递给assemply函数时,您将获得指向作为数组内容的内存区域的指针 .

    要检索参数,它取决于您使用的调用约定 . ARM EABI规定:

    前四个寄存器r0-r3(a1-a4)用于将参数值传递给子程序并从函数返回结果值 . 它们也可用于在例程中保存中间值(但通常仅用于子例程调用之间) .

    对于简单的函数,你应该在r0到r4中找到指向数组的指针,具体取决于你的函数签名 . 否则,您将在堆栈中找到它 . 一个很好的技术可以准确地找出ABI的内容,即反汇编调用汇编函数的C代码的目标文件,并在调用Assembly函数之前检查它的作用 .

    例如,在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
    

    您可以通过将参数放入寄存器 r0 来查看单参数函数 myasmfunc . ldr r0, [pc, #12] 的含义是“加载到 r0 内存地址的内容 pc+12 ” . 这是存储指向数组的指针的地方 .

  • 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值,并且因为数组元素的地址没有改变,所以我只使用相同的数组来输出结果 .

相关问题