C 语言函数调用和VLA和alloca栈的变化探讨
NOTE: 以下讨论使用的平台为 x86-64,使用的编译器为 gcc,以下提供的伪汇编码 采用 intel 格式。 文章中提到的代码,可以在 Code 找到。 一些重要的寄存器和指令 函数调用过程中,比较重要的寄存器主要有三个 rip rbp rsp。 rip 寄存器存放的为下一条要执行指令的地址,Instruction Pointer。 rbp 为基寄存器,存放的为前一个 rbp 的值,Base Pointer。 rsp 为栈寄存器,一直指向函数调用栈的底部,Stack Pointer。 比较重要的指令有 call push pop leave ret。 call addr 指令会首先将 call 返回之后要执行的地址压入栈中(返回地址),设置 rip 的值为 addr,然后跳转的这个位置去执行,大致可以等效于一下指令。 # 假设当执行到 call 指令时 CPU 就会自动设置 rip 寄存器为下一条要执行的指令 push rip mov rip, addr # 按理设置了 rip 寄存器,CPU 就会去执行 rip 地址的指令,这里写 jmp 只是想要更清晰的表示 call 的流程 jmp addr push rbp 指令会将 rsp 寄存器下移一个 word 的长度,rbp 中的内容移动到 rsp 寄存器所指向的地址中。 ...