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

时间:2011-12-12 23:33:35

标签: assembly stack arm

这是一个家庭作业问题。我正在尝试调用FOO(A,B,C,D,E,F)形式的函数。前四个参数在寄存器r0-r3中。最后两个分别位于r7r6中,因此它们是向后的。如何将参数压入堆栈,使它们按正确顺序排列?

STMFD sp! {r0-r3}然后是STMFD sp! {r7, r6, lr}吗?我正在使用完全下降的堆栈。

this site上的图表是否正确,因为STMFD r13!, {r4-r7}如果最先存储最低寄存器,那么r4 r7不应该{{1}}?

4 个答案:

答案 0 :(得分:7)

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

STMFD SP!, {R0-R3}
STMFD SP!, {R3, R2, R1, R0}
STMFD SP!, {R1-R2, R0, R3}

答案 1 :(得分:2)

我认为肯尼得到了正确的答案。

如果您还没有找到关于该主题的文档,我还会找到一些文档:ARM describes the most common calling convention hereThis website还详细介绍了在C和ASM之间进行调用(这反过来说明了调用约定)。

答案 2 :(得分:2)

为什么不尝试呢?

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

llvm给出:

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

由于这是作业,我将由您决定是否可以使用带有多个寄存器的单个stm / push指令(如其他答案所述,您不能控制具有多个寄存器的堆栈上的顺序)或多个stm / push指令,每个寄存器一个。 (或弄清楚如何制作一个能够显示答案的测试程序)

知道约定是好的,但你可以回答这些问题而不完整阅读约定,使用符合约定的编译器或两个。基本上不要假设你从一些反汇编中知道关于约定的一切,例如你没有告诉我们a,b,c,d,e,f是64位整数,双浮点数,字节,半字,单词等等。堆栈上的东西肯定会受到影响,但是,无论你是否可以使用多个寄存器的stm / push指令来获取它,都可能会保持一致。

编辑:

是的,该网页是正确的,您需要获取并阅读ARM ARM(现在每个系列都有一个单独的ARM ARM(ARM架构参考手册))。它们具有用伪代码等定义的指令。在这种情况下:

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).

答案 3 :(得分:1)

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