汇编编程中的寄存器保存、数据处理与系统调用
1. 寄存器保存
在汇编编程里,PUSH 指令会把 64 位寄存器的值压入栈中。在返回调用者之前,这些值会一直安全地存于栈内,之后再通过 POP 指令把它们弹出到相同的寄存器。示例代码如下:
pop rdi
pop rsi
pop rbx
ret
这里有个关键细节,如果顺序错误会引发大量奇怪的程序错误。调用者的值必须按照与压入时相反的顺序从栈中弹出。比如,先压入 RBX,接着是 RSI,最后是 RDI,那么弹出时就得按 RDI、RSI、RBX 的顺序。虽然 CPU 会按你编写的顺序把栈中的值弹出到任意寄存器,但顺序错误就会改变调用者的寄存器,而非保存它们。
保存寄存器的最佳方式是在过程内部对该过程所改变的寄存器进行压栈和出栈操作。不过,传递值给过程的寄存器除外,因为这些寄存器是调用者在调用过程之前有意改变的。
2. Linux 系统调用中的寄存器保存
Linux 系统调用也会使用寄存器。SYSCALL 指令本身会使用两个寄存器:
- SYSCALL 把返回地址存于 RCX 寄存器。
- SYSCALL 把 RFlags 存于 R11 寄存器。
每次执行 SYSCALL 时,RCX 和 R11 都会被覆盖。系统调用时的寄存器使用可分为三类:
- 需要通过寄存器给系统调用代码传递参数。
- 系统调用代码自身会使用一些额外的寄存器。
- 系统调用可能会在寄存器中返回代码可能需要的值。
在 x64 Linux 中,系统调
超级会员免费看
订阅专栏 解锁全文
2万+

被折叠的 条评论
为什么被折叠?



