ARM Arch64中的PUSH {lr}和POP {lr}

jkg*_*jkg 2 assembly arm arm64

什么是等效的指令PUSH{lr},并POP{lr}在ARM Arch64指令集.

是对的STR X30, [SP, #8]吗?你能解释一下保持堆栈对齐的概念吗?我对ARMv8比较陌生,请原谅.

Bit*_*ank 7

如果您要求C编译器从源代码生成汇编语言列表,您将看到它如何处理ARMv8堆栈上的数据推送.这可能不是唯一的方法,但GCC这样做:

   sub  sp, sp, #32     \\ Open up some temp stack space
   stp  x19, x20, [sp]  \\ save 2 pairs of registers
   stp  x21, x30, [sp,#16]
 <your code>
   ldp  x19, x20, [sp]  \\ restore 2 pairs of registers
   ldp  x21, x30, [sp,#16]
   add  sp, sp, #32     \\ "free" the temp stack space
Run Code Online (Sandbox Code Playgroud)


use*_*812 6

STR X30, [SP, #8]是完全错误的。

  1. 关于 Aarch64 堆栈最重要的一点是SP 必须是 16 字节对齐

  2. 堆栈正在下降。所以SP应该向左移动。sub sp, sp, #CONST。在您的示例中,您实际上弄乱了父函数的数据。


如果您需要保留Aarch64 中LR实际使用的内容x30

str         x30,        [sp,#-16]!
Run Code Online (Sandbox Code Playgroud)


从技术上讲,只能通过以下方式保存在寄存器上:

str         x30,        [sp,#-8]  // sp is not changed here! but data is written in permitted area
Run Code Online (Sandbox Code Playgroud)

但假设您的函数不调用任何其他子函数。但LR在这种情况下到底为什么要保存呢?

Aarch64 还可以使用任何其他寄存器来执行函数的返回。例如:

mov x7, x30 // preserve LR
blr .L.my.bloody.subroutine   // blr will mess up LR/x30
...
ret x7      // returning from function by using preserved req
Run Code Online (Sandbox Code Playgroud)


如果您需要保留 2 个以上寄存器,请使用 @BitBank 提供的示例


最后,您无法修改pc,因此只有一种方法可以使用返回ret