为什么push指令会改变rsp的值?

Mir*_*vel 0 c assembly x86-64

我正在检查 Ericksons Hacking: The Art of Exploitation 中的这段代码片段:

\n
void test_function(int a, int b, int c, int d) {\n        int flag;\n        char buffer[10];\n        flag = 31337;\n        buffer[0] = \'A\';\n}\n\nint main() {\n        test_function(1, 2, 3, 4); \n}\n
Run Code Online (Sandbox Code Playgroud)\n
void test_function(int a, int b, int c, int d) {\n        int flag;\n        char buffer[10];\n        flag = 31337;\n        buffer[0] = \'A\';\n}\n\nint main() {\n        test_function(1, 2, 3, 4); \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我在 main 和 test_function 处设置了断点。\n当中断 main 时,我得到以下输出:

\n
gcc -g stack_example.c\n\ngdb -q ./a.out\n\ngef\xe2\x9e\xa4list main\n\n\n     0x555555555192 <main+0>         endbr64 \n       0x555555555196 <main+4>         push   rbp\n       0x555555555197 <main+5>         mov    rbp, rsp\n     \xe2\x86\x92 0x55555555519a <main+8>         mov    ecx, 0x4\n       0x55555555519f <main+13>        mov    edx, 0x3\n       0x5555555551a4 <main+18>        mov    esi, 0x2\n       0x5555555551a9 <main+23>        mov    edi, 0x1\n       0x5555555551ae <main+28>        call   0x555555555149 <test_function>\n       0x5555555551b3 <main+33>        mov    eax, 0x0\n
Run Code Online (Sandbox Code Playgroud)\n

现在,当我在 test_function 处中断时,寄存器包含:

\n
gef\xe2\x9e\xa4  i r rsp rbp rip\n\n    rsp            0x7fffffffdfc8      0x7fffffffdfc8\n    rbp            0x0                 0x0\n    rip            0x555555555192      0x555555555192 <main>\ngef\xe2\x9e\xa4 x/8i $rip\n\n       0x555555555192 <main>:   endbr64 \n       0x555555555196 <main+4>: push   rbp\n       0x555555555197 <main+5>: mov    rbp,rsp\n       0x55555555519a <main+8>: mov    ecx,0x4\n       0x55555555519f <main+13>:    mov    edx,0x3\n       0x5555555551a4 <main+18>:    mov    esi,0x2\n       0x5555555551a9 <main+23>:    mov    edi,0x1\n       0x5555555551ae <main+28>:    call   0x555555555149 <test_function>\n\ngef\xe2\x9e\xa4continue\n
Run Code Online (Sandbox Code Playgroud)\n

我的问题是,为什么寄存器 rsp 从0x7fffffffdfc8变为0x7fffffffdfc0在这些指令之后

\n
    0x555555555196 <main+4>         push   rbp\n    0x555555555197 <main+5>         mov    rbp, rsp\n
Run Code Online (Sandbox Code Playgroud)\n

Mar*_*lli 5

该指令的push rbp作用与 相同sub rsp, 8; mov QWORD PTR[rsp], rbp;。它首先将堆栈指针 ( rsp) 向上移动 8 个字节(这是因为 x86-64 中寄存器的大小为 8 个字节,即 64 位),然后将寄存器的值移动到它所指向的内存位置。因此, 的值rsp,即0x7fffffffdfc8,变为0x7fffffffdfc0,比之前少了 8。

  • `sub` 不是一个准确的解释,因为 `push` 不会改变标志。`lea rsp, [rsp - 8]` 更接近。 (5认同)