所以我正在 gdb 中调试一个简单的 c 程序,如下所示,查看程序集
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = 12;
printf("%d\n", a);
}
汇编代码如下
0x0000000000001139 <+0>: push rbp
0x000000000000113a <+1>: mov rbp,rsp
0x000000000000113d <+4>: sub rsp,0x10
0x0000000000001141 <+8>: mov DWORD PTR [rbp-0x4],0xc
0x0000000000001148 <+15>: mov eax,DWORD PTR [rbp-0x4]
0x000000000000114b <+18>: mov esi,eax
0x000000000000114d <+20>: lea rax,[rip+0xeb0] # 0x2004
0x0000000000001154 <+27>: mov rdi,rax
0x0000000000001157 <+30>: mov eax,0x0
0x000000000000115c <+35>: call 0x1030 <printf@plt>
0x0000000000001161 <+40>: mov eax,0x0
0x0000000000001166 <+45>: leave
0x0000000000001167 <+46>: ret
变量 a 首先在堆栈中,然后在 eax 中,然后在 esi(rsi) 中,因为 printf 采用一个参数,所以我们最终将数据移动到 rsi 中,这是调用约定中的第二个参数 然而第一个参数“%d “必须通过调用约定以某种方式再次存储在 rdi 中,但是检查 rdi 显示它不存储它。
它是否存储在堆栈中的某个位置,或者 rdi 是否指向它,请向我解释一下,有关调用约定的信息来自此来源
http://6.s081.scripts.mit.edu/sp18/x86-64-architecture-guide.html
尝试将数据转换为字符串或其他东西,但都不起作用
字符串
"%d\n"
存储在只读数据段中。这一系列指令涉及它:
lea rax,[rip+0xeb0] ; retrieve string address
mov rdi,rax ; provide string address as first argument
在跳过 LEA 指令后,您可以使用 gdb 命令检查字符串:
printf (char *)$rax