【问题标题】:ARM Assembly: How to pass and make use of a array of pointers inside an ARM Assembly functionARM 汇编:如何在 ARM 汇编函数中传递和使用指针数组
【发布时间】:2010-09-29 16:13:44
【问题描述】:

我有一个 C 函数,其中有 4 个指针,每个指针指向大型 2D 浮点数组的不同位置。

因为 ARM 汇编函数只能传递 4 个参数 (r0 - r3),我无法理解如何将指针传递给我的返回值,这将成为我的汇编函数的第 5 个参数。

所以,为了克服这个问题,我想将所有 4 个指针放入一个指针数组中,这样我将有 3 个空闲点,使用它们我也可以将指针传递给我的返回值。

但是,我不知道如何从汇编函数内部的指针数组中提取四个单独的指针。我的尝试失败了。

这是我正在尝试做的一个示例。

程序

#include<stdio.h>

void  _my_arm_asm(float32_t *);

float32_t data_array[100][100];

void main()
{
       float32_t *ptr1, *ptr2, *ptr3, *ptr4;

        ptr1 = \\ data_array[value] + (some value);
        ptr2 = \\ data_array[value] + (some other value);
        ptr3 = \\ data_array[value] + (some other value);
        ptr4 = \\ data_array[value] + (some other value);

       float32_t *array_pointers[4];
       array_pointers[0] = ptr1;
       array_pointers[1] = ptr2;
       array_pointers[2] = ptr3;
       array_pointers[3] = ptr4;

       float32x4_t result;

       _my_arm_asm(array_pointers, &result);

        ....
        ....
        ....
       return 0;


}



.text
    .global _my_arm_asm

_my_arm_asm:
            #r0: Pointer to my array of pointers
            #r1: Pointer to my result

        push   {r4-r11, lr}

        # How to access the array of pointers?

        # I previously tried this, is this the right way to do it?

        # mov r4, #0
        # vld4.32 {d0, d1, d2, d3}, [r0, r4]
        # add r4, r4, #1
        # vld4.32 {d4, d5, d6, d7}, [r0, r4] 
        # add r4, r4, #1
        # vld4.32 {d8, d9, d10, d11}, [r0, r4] 
        # add r4, r4, #1
        # vld4.32 {d12, d13, d14, d15}, [r0, r4] 


        ....
        ....
        ....

        pop    {r4-r11, pc}

【问题讨论】:

  • 你应该展示你在组装方面的尝试。
  • 遇到此类问题时,最好的方法是用 C 编写一个存根函数,然后使用 gcc -S 将其编译为汇编源代码 - 然后您可以使用生成的汇编源代码作为模板你的功能。

标签: c arrays pointers assembly arm


【解决方案1】:

一般来说,如果超过 4 个参数被传递给一个函数,多余的参数就会被传递到堆栈中。

ARM EABI 指定编译器应如何将参数传递给函数(它还指定调用者可以期望在函数调用中保持不变的寄存器)。您的汇编程序可以使用相同的技术(并且可能应该使用,除非您有充分的理由不这样做)。如果不出意外,这意味着你的汇编函数可以很容易地从 C 中调用。

“ARM 体系结构的过程调用标准”的第 5 章(基本过程调用标准)应该有确切的细节。从表面上看,它非常复杂(因为有很多关于对齐、参数大小等的细节),但我认为出于您的目的,它归结为函数 get 的第 5 个参数被推入堆栈。

当然,正如您在问题中所建议的那样,您可以通过将 4 个指针打包到一个结构中并将一个指针传递给该结构来避免所有这些 - 在您的汇编例程中,您只需将该结构指针加载到一个寄存器中并使用它依次加载您真正需要的指针。

我认为 ARM 程序集可能类似于:

                 // r0 has the 1st parameter
ldr r4, [r0]     // get array_pointers[0] into r4
// ...

ldr r5, [r0, #4] // get array_pointers[1] into r5
// ...

ldr r6, [r0, #8] // get array_pointers[2] into r6

您也可以使用“加载多个”指令一次性获取所有 4 个指针,但我不确定您注册的使用要求/限制可能是什么。

【讨论】:

  • 迈克尔,是的,我按照你的建议做了,我将所有指针打包到一个结构中并将其传递给汇编函数,我可以使用 ldr 访问它们。
【解决方案2】:

第五个和更多参数(假设是 int 大小的参数)在堆栈上传递。 IE。第五个参数可作为 [SP] 访问,第六个参数可作为 [SP,#4] 访问,依此类推。阅读Procedure Call Standard for the ARM Architecture了解详细说明。
也就是说,您不必使用汇编来使用 NEON。查看NEON intrinsics,它允许您使用纯 C 代码执行所有操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2015-02-25
    • 2022-08-11
    • 1970-01-01
    相关资源
    最近更新 更多