Assembly 在Arm中,参数存储在堆栈上的顺序是什么?

Assembly 在Arm中,参数存储在堆栈上的顺序是什么?,assembly,stack,arm,Assembly,Stack,Arm,这是一个家庭作业问题。我试图调用一个形式为FOO(a,B,C,D,E,F)的函数。前四个参数位于寄存器r0-r3中。最后两个分别位于r7和r6,因此它们是向后的。如何将参数推送到堆栈上,使其顺序正确 是STMFD sp!{r0-r3}thenSTMFD sp!{r7,r6,lr}?我正在使用一个完整的下降堆栈 上的图表是否正确,因为当它执行STMFD r13!,{r4-r7}不应该r4在r7的位置,如果首先存储最低寄存器?在ARM中,寄存器列表的顺序无关紧要。它将始终从最低寄存器(R0、R1、R

这是一个家庭作业问题。我试图调用一个形式为
FOO(a,B,C,D,E,F)
的函数。前四个参数位于寄存器
r0-r3
中。最后两个分别位于
r7
r6
,因此它们是向后的。如何将参数推送到堆栈上,使其顺序正确

STMFD sp!{r0-r3}
then
STMFD sp!{r7,r6,lr}
?我正在使用一个完整的下降堆栈


上的图表是否正确,因为当它执行
STMFD r13!,{r4-r7}
不应该
r4
r7
的位置,如果首先存储最低寄存器?

在ARM中,寄存器列表的顺序无关紧要。它将始终从最低寄存器(R0、R1、R2,…)开始存储以下内容(如果汇编程序接受):


我想肯尼得到了正确的答案

我还找到了一些关于这个主题的文档,如果您还没有找到的话:。还有关于C和ASM之间调用的详细信息(这反过来又说明了调用约定)。

为什么不试试呢

unsigned int foo ( unsigned int a, unsigned int b, unsigned int c,
unsigned int d, unsigned int e, unsigned int f )
{

    return(a+b+c+d+e-f);

}
在某种程度上,gcc给出了

00000000 <foo>:
   0:   e0810000    add r0, r1, r0
   4:   e080c002    add ip, r0, r2
   8:   e08c1003    add r1, ip, r3
   c:   e59d3000    ldr r3, [sp]
  10:   e59d2004    ldr r2, [sp, #4]
  14:   e0810003    add r0, r1, r3
  18:   e0620000    rsb r0, r2, r0
  1c:   e12fff1e    bx  lr

寄存器按从低到高的顺序传输,因此R15(如果在列表中)将始终最后传输。最低的寄存器也会被传输到最低的内存地址。

难道你不能交换到寄存器值然后再交换到stmfd r0-r3、r6、r7、lr吗?@MichaelDorgan:我认为这只是作业设定的一种人为约定。ARM ABI(至少对于iPhone而言)按r0、r1、r2、r3、[sp]、[sp,4]、[sp,8]、,。。。当没有结构返回时。r6、r7只是两个通用的持久寄存器。使用完整的递减堆栈,这意味着R0将位于最高地址、R1较低地址、甚至R2较低地址等?但仅当使用一个STMFD(例如STMFD sp)推送它们时!{R0-R3}与执行STMFD sp不同!{R0}STMFD sp!{R1}STMFD sp!{R2}STMFD sp!{R3}@quest4knoledge:不,无论STMxx的寻址模式如何,R0始终是最低的。如果您不确定,请阅读ARM,它包含LDMxx/STMxx如何执行的伪代码。好的,我误解了您所说的“它将始终从最低的寄存器开始存储”的意思。我以为您的意思是,最低的寄存器将首先存储,然后第二个最低的寄存器在堆栈上继续存储(因此位于较低的地址)。因此,最低的寄存器首先存储在堆栈的顶部(堆栈的顶部被视为较低的地址)?@quest4knoledge:仅存储最低的地址。堆栈顶部的位置无关。您的意思是“ARM描述了最常见的…”;尽管IBM可能会对ARM提出要求,但事实并非如此;-)“询问机器”的问题在于,您不知道是否可以保证您正在使用的行为(无论是CPU、编译器、DLL还是其他)与下一版本的行为相匹配。特别是在进行前沿开发时:“我们修复了那个bug”。
00000000 <foo>:
   0:   e0810000    add r0, r1, r0
   4:   e080c002    add ip, r0, r2
   8:   e08c1003    add r1, ip, r3
   c:   e59d3000    ldr r3, [sp]
  10:   e59d2004    ldr r2, [sp, #4]
  14:   e0810003    add r0, r1, r3
  18:   e0620000    rsb r0, r2, r0
  1c:   e12fff1e    bx  lr
00000000 <foo>:
   0:   e0810000    add r0, r1, r0
   4:   e59d1000    ldr r1, [sp]
   8:   e0800002    add r0, r0, r2
   c:   e59d2004    ldr r2, [sp, #4]
  10:   e0800003    add r0, r0, r3
  14:   e0800001    add r0, r0, r1
  18:   e0400002    sub r0, r0, r2
  1c:   e1a0f00e    mov pc, lr
The registers are stored in sequence, the lowest-numbered register to the lowest
memory address (start_address), through to the highest-numbered register to the
highest memory address (end_address).