Mar*_*ark 5 c assembly stack x86-64 red-zone
这就是我通过阅读一些内存分段文档所理解的:当调用一个函数时,有一些指令(称为函数序言)将帧指针保存在堆栈上,将堆栈指针的值复制到基本指针中并保存一些局部变量的内存.
这是我尝试使用GDB调试的一个简单代码:
void test_function(int a, int b, int c, int d) {
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main() {
test_function(1, 2, 3, 4);
}
Run Code Online (Sandbox Code Playgroud)
调试此代码的目的是了解调用函数时堆栈中发生的情况:因此我必须在执行程序的各个步骤(在调用函数之前和执行期间)检查内存.虽然我设法通过检查基指针来查看返回地址和保存的帧指针之类的东西,但我真的无法理解在反汇编代码之后我要写的内容.
拆解:
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400509 <+0>: push rbp
0x000000000040050a <+1>: mov rbp,rsp
0x000000000040050d <+4>: mov ecx,0x4
0x0000000000400512 <+9>: mov edx,0x3
0x0000000000400517 <+14>: mov esi,0x2
0x000000000040051c <+19>: mov edi,0x1
0x0000000000400521 <+24>: call 0x4004ec <test_function>
0x0000000000400526 <+29>: pop rbp
0x0000000000400527 <+30>: ret
End of assembler dump.
(gdb) disassemble test_function
Dump of assembler code for function test_function:
0x00000000004004ec <+0>: push rbp
0x00000000004004ed <+1>: mov rbp,rsp
0x00000000004004f0 <+4>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004f3 <+7>: mov DWORD PTR [rbp-0x18],esi
0x00000000004004f6 <+10>: mov DWORD PTR [rbp-0x1c],edx
0x00000000004004f9 <+13>: mov DWORD PTR [rbp-0x20],ecx
0x00000000004004fc <+16>: mov DWORD PTR [rbp-0x4],0x7a69
0x0000000000400503 <+23>: mov BYTE PTR [rbp-0x10],0x41
0x0000000000400507 <+27>: pop rbp
0x0000000000400508 <+28>: ret
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
我理解"将帧指针保存在堆栈上"是通过"push rbp"来完成的,"将堆栈指针的值复制到基本指针"是由"mov rbp,rsp"完成的,但令我困惑的是缺少"sub rsp $ n_bytes"表示"为局部变量保存一些内存".我在很多展览中看到过(甚至在stackoverflow上的一些主题).
我还读到,参数应该与基指针有一个正偏移(在它填充堆栈指针值之后),因为如果它们位于调用函数中并且堆栈向低地址增长,那么当基本指针时它是完全合理的使用堆栈指针值更新编译器通过添加一些正数在堆栈中返回.但是我的代码似乎将它们存储在负偏移中,就像局部变量一样.我也无法理解为什么它们被放入那些寄存器(在主要中)..它们不应该直接保存在rsp中"偏移" "?
也许这些差异是由于我使用64位系统这一事实,但我的研究并没有引导我去解释我所面临的任何问题.
System V ABI for x86-64指定red zone下面的128个字节%rsp.这些128个字节属于该函数,只要它不调用任何其他函数(它是a leaf function).中断处理程序需要尊重红区,因为它们实际上是非自愿的函数调用.
您的所有局部变量(test_function叶子函数)都适合红色区域,因此无需进行调整%rsp.(此外,该功能没有明显的副作用,并且会在任何合理的优化设置上进行优化).