这是一个家庭作业问题。我正在尝试调用FOO(A,B,C,D,E,F)
形式的函数。前四个参数在寄存器r0-r3
中。最后两个分别位于r7
和r6
中,因此它们是向后的。如何将参数压入堆栈,使它们按正确顺序排列?
是STMFD sp! {r0-r3}
然后是STMFD sp! {r7, r6, lr}
吗?我正在使用完全下降的堆栈。
this site上的图表是否正确,因为STMFD r13!, {r4-r7}
如果最先存储最低寄存器,那么r4
r7
不应该{{1}}?
答案 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 here。 This 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(如果在列表中)将始终最后传输。最低寄存器也会从最低存储器地址传输。