Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在ARM汇编函数中访问4个以上的参数?_Assembly_Arm - Fatal编程技术网

Assembly 如何在ARM汇编函数中访问4个以上的参数?

Assembly 如何在ARM汇编函数中访问4个以上的参数?,assembly,arm,Assembly,Arm,在我的汇编函数中,有6个参数。当我尝试访问第四个和第五个参数时,它们是错误的,这是我在arm cortex-8a上的代码 push {r4-r8,lr} ldr r6, [sp] ldr r7, [sp, #4] 我已检查[sp]内存,r4-r8的值错误。但是,如果有3个或更少的参数,[sp]给出正确的r4-r8值。我遗漏了什么吗?额外的参数在堆栈上传递,但是,SP在函数的入口指向它们。在prolog中,您正在推送要保存的寄存器,这会更改SP,因此您需要对其进行说明 r4、r5、r6、r7、r

在我的汇编函数中,有6个参数。当我尝试访问第四个和第五个参数时,它们是错误的,这是我在arm cortex-8a上的代码

push {r4-r8,lr}
ldr r6, [sp]
ldr r7, [sp, #4]

我已检查[sp]内存,r4-r8的值错误。但是,如果有3个或更少的参数,[sp]给出正确的r4-r8值。我遗漏了什么吗?

额外的参数在堆栈上传递,但是,
SP
在函数的入口指向它们。在prolog中,您正在推送要保存的寄存器,这会更改
SP
,因此您需要对其进行说明

r4、r5、r6、r7、r8和lr是6个寄存器,因此您需要将
SP
偏移量调整6*4=24字节。因此,请尝试以下方法:

push {r4-r8,lr}        // 6 regs are pushed
                       // SP is decremented by 6*4 = 24 bytes
ldr r6, [sp, #(0+24)]  // get first stack arg
ldr r7, [sp, #(4+24)]  // get second stack arg
如果您使用
SP
执行更多操作,例如为堆栈变量分配空间,您可能也必须考虑到这一点。

为什么不试试呢

unsigned int fun ( unsigned int, unsigned int, unsigned int, unsigned int, unsigned int );
unsigned int myfun ( void )
{
return(fun(1,2,3,4,5));
}
组装然后拆卸

> arm-none-eabi-gcc -O2 -c fun.c -o fun.o
> arm-none-eabi-objdump -D fun.o 
arm-none-eabi-gcc -O2 -c fun.c -o fun.o
arm-none-eabi-objdump -D fun.o 

00000000 <fun>:
   0:   e0811000    add r1, r1, r0
   4:   e0812002    add r2, r1, r2
   8:   e59d0000    ldr r0, [sp]
   c:   e0823003    add r3, r2, r3
  10:   e0600003    rsb r0, r0, r3
  14:   e12fff1e    bx  lr
程序集输出包含

00000000 <myfun>:
   0:   e52de004    push    {lr}        ; (str lr, [sp, #-4]!)
   4:   e3a03005    mov r3, #5
   8:   e24dd00c    sub sp, sp, #12
   c:   e58d3000    str r3, [sp]
  10:   e3a01002    mov r1, #2
  14:   e3a02003    mov r2, #3
  18:   e3a03004    mov r3, #4
  1c:   e3a00001    mov r0, #1
  20:   ebfffffe    bl  0 <fun>
  24:   e28dd00c    add sp, sp, #12
  28:   e49de004    pop {lr}        ; (ldr lr, [sp], #4)
  2c:   e12fff1e    bx  lr
组装和拆卸

> arm-none-eabi-gcc -O2 -c fun.c -o fun.o
> arm-none-eabi-objdump -D fun.o 
arm-none-eabi-gcc -O2 -c fun.c -o fun.o
arm-none-eabi-objdump -D fun.o 

00000000 <fun>:
   0:   e0811000    add r1, r1, r0
   4:   e0812002    add r2, r1, r2
   8:   e59d0000    ldr r0, [sp]
   c:   e0823003    add r3, r2, r3
  10:   e0600003    rsb r0, r0, r3
  14:   e12fff1e    bx  lr

看到编译器实际实现了调用约定可以使对调用约定本身的读取更容易理解。或者,如果你在你感兴趣的编译器上为你感兴趣的特定函数原型制作了这样的示例,你不必阅读约定,只要让你感兴趣的调用者或被调用者匹配编译器本身的功能即可。

AAPCS标准

5.5参数传递包含答案

由于它是一种算法,所以理解起来并不容易,但回答这个问题的关键部分似乎是:

C.5 如果NCRN小于r4,且NSAA等于SP,则参数在core之间拆分 寄存器和堆栈。论证的第一部分是c 从 NCRN达到并包括r3。参数的其余部分将复制到堆栈中,从 国安局。NCRN设置为r4,NSAA按参数大小减去 通过的金额 在登记册中。该参数现在已分配


正如其他人所说,这意味着4个寄存器+堆栈。

额外的12个字节将保持
sp
与ABI要求的16个字节的倍数对齐。