例如,在以下代码中 “justatest”和格式“%s”在堆中定义:
char str[15]="justatest";
int main(){
printf("%s",str);
return 0;
}
在GDB中,我在调用printf之前获得了汇编代码:
=> 0x0804841f <+14>: movl $0x804a020,0x4(%esp)
0x08048427 <+22>: movl $0x80484d8,(%esp)
0x0804842e <+29>: call 0x80482f0 <printf@plt>
我是否必须使用“x / s 0x804a020”和“x / s 0x80484d8”检查参数1by1
或者堆中定义的常量表是否可以直接引用?
谢谢!
答案 0 :(得分:1)
您对 str 驻留在堆上的理解不正确。其全局变量存储在数据段中。关于print global变量,您可以在我的GNU / Linux终端上执行以下操作。
$ gcc -g -Wall hello.c
$ gdb -q ./a.out
Reading symbols from /home/mantosh/practice/a.out...done.
(gdb) break main
Breakpoint 1 at 0x400524: file hello.c, line 6.
(gdb) run
Starting program: /home/mantosh/practice/a.out
Breakpoint 1, main () at bakwas.c:6
6 printf("%s",str);
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400520 <+0>: push %rbp
0x0000000000400521 <+1>: mov %rsp,%rbp
=> 0x0000000000400524 <+4>: mov $0x601020,%esi
0x0000000000400529 <+9>: mov $0x4005e4,%edi
0x000000000040052e <+14>: mov $0x0,%eax
0x0000000000400533 <+19>: callq 0x4003f0 <printf@plt>
0x0000000000400538 <+24>: mov $0x0,%eax
0x000000000040053d <+29>: pop %rbp
0x000000000040053e <+30>: retq
End of assembler dump.
(gdb) p str
$1 = "justatest\000\000\000\000\000"
(gdb) p &str
$2 = (char (*)[15]) 0x601020
// These are addresses of two arguments which would be passed in printf.
// From assembly instruction we can verify that before calling the printf
// these are getting stored into the registers.
(gdb) x/s 0x4005e4
0x4005e4: "%s"
(gdb) x/s 0x601020
0x601020 <str>: "justatest
答案 1 :(得分:1)
后来我发现没有调试符号表的对象文件
objdump -t obj
将包含全局变量/函数的大多数符号及其地址 ,和
objdump -D obj instead of -d
将包含所有部分,例如.text / .data / .rodata而不是.text only
这两个组合提供了对上面提到的内容的充分访问,例如switch表/ const字符串/全局变量