我有一个C函数,其中我有4个指针,每个指针都指向一个大型浮点数组的不同位置。
因为ARM汇编函数只能传递4个参数(r0-r3),所以我无法理解如何将指针传递给我的返回值,这将成为汇编函数的第5个参数。 / p>
所以,为了克服这个问题,我想把所有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}
答案 0 :(得分:4)
通常,如果将超过4个参数传递给函数,则会在堆栈上传递多余的参数。
ARM EABI指定编译器应如何将参数传递给函数(它还指定调用者可以期望在函数调用中保持不变的寄存器)。您的汇编例程可以使用相同的技术(除非您有充分的理由,否则可能应该这样做)。如果没有别的,那就意味着你可以从C轻松调用你的汇编函数。
“ARM体系结构的过程调用标准”的第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
您也可以使用'load multiple'指令一次性获取所有4个指针,但我不确定您注册的使用要求/限制可能是什么。
答案 1 :(得分:3)
第五个和更多参数(假设int大小的参数)在堆栈上传递。即第五个参数可以作为[SP]访问,第六个参数可以作为[SP,#4],依此类推。请阅读Procedure Call Standard for the ARM Architecture以获取详细说明 也就是说,您不必使用组件来使用NEON。查看NEON intrinsics,它允许您使用纯C代码执行所有操作。