See*_*und 1 assembly stack arm subroutine
用于 ARM 组装
我一直在我的子程序中执行以下操作:
SubRoutine:
PUSH {r1,r2,lr}
//code that changes r1 and r2
POP {r1,r2,lr}
bx lr
Run Code Online (Sandbox Code Playgroud)
这是从子程序返回并继续执行主函数中代码的正确方法吗?我看到周围的人正在做以下事情:
SubRoutine:
PUSH {r1,r2,lr}
//code that changes r1 and r2
POP {r1,r2,pc}
bx lr
Run Code Online (Sandbox Code Playgroud)
但我不知道为什么你在推 LR 时会 POP 电脑。哪个是正确的方法,为什么?
此外,如果您在子例程中调用子例程,请执行以下操作:
SubRoutine:
PUSH {r1,r2,lr}
//code that changes r1 and r2
PUSH {lr}
bl AnotherRoutine (where bx lr will be used to return from it)
POP {lr}
POP {r1,r2,pc}
bx lr
Run Code Online (Sandbox Code Playgroud)
或者你是这样做的:
SubRoutine:
PUSH {r1,r2,lr}
//code that changes r1 and r2
PUSH {lr}
bl AnotherRoutine(where bx lr will be used to return from it)
POP {pc}
POP {r1,r2,pc}
bx lr
Run Code Online (Sandbox Code Playgroud)
您应该注意三种情况。
void foo(void) {};int foo(void) { return bar(); };int foo(void) { int i; i = bar() + 4; return i; };有很多方法可以实现这些调用。下面是一些示例,并不是在 ARM 汇编程序中实现结语和序言的唯一方法。
叶函数
许多函数是叶子类型,不需要保存lr. 您只需使用bx lr来返回。例如,
SubRoutine:
PUSH {r1,r2}
//code that changes r1 and r2
POP {r1,r2}
bx lr
Run Code Online (Sandbox Code Playgroud)
此外,通常使用 r1 和 r2 传递参数,并且子程序可以自由使用/销毁它们。ARM 调用约定 如果您从汇编程序中调用“C”函数,就会出现这种情况。所以通常情况下,没有人会保存 r1 和 r2,但由于它是汇编程序,您可以随心所欲地做任何事情(即使这是一个坏主意)。所以实际上这个例子只有bx lr在你遵循标准的情况下。
尾呼叫
如果你的函数是一个叶子,除了对另一个函数的最终调用,你可以使用以下快捷方式,
Sub_w_tail:
// Save callee-saved regs (for whatever calling convention you need)
// Leave LR as is.
// ... do stuff
B tail_call
Run Code Online (Sandbox Code Playgroud)
在LR被调用者保存Sub_w_tail,你只要直接跳转到tail_call其返回到原来的调用者。
中间函数
这是最复杂的。这是一个可能的顺序,
SubRoutine:
PUSH {r1,r2,lr}
//code that changes r1 and r2
bl AnotherRoutine (where bx lr will be used to return from it)
// more code
POP {r1,r2,pc} // returns to caller of 'SubRoutine'
Run Code Online (Sandbox Code Playgroud)
旧调用约定的一些详细信息在ARM 链接和帧寄存器问题中。您可以使用此约定。在 ARM 汇编程序中执行结语和序言的方法有很多种。
最后一个相当复杂;或者至少编码很乏味。让编译器决定使用哪些寄存器以及将哪些放在堆栈上会好得多。但是,通常在编写汇编程序时您只需要知道如何编写第一个(LEAF函数)。仅在汇编程序中编写从高级语言调用的优化子例程的效率最高。了解它们如何工作以理解编译后的代码很有用。您还应该考虑内联汇编器,这样您就不必处理这些细微差别。
| 归档时间: |
|
| 查看次数: |
4142 次 |
| 最近记录: |