我试图找出如何打印整数值(我看到它是x / d),但我遗漏了一些东西。
所以,我的代码是以下
1 #include <stdio.h>
2 main(){
3 int a;
4 int b;
5 int c;
6 int d;
7 int multiplied;
8 a = 5;
9 b = 6;
10 c = 7;
11 d = adding(a,b,c);
12 multiplied = multiply(a,b,c);
13 printf("The value of d is %d \n",d);
14 printf("The multiplied values are %d \n", multiplied);
15 }
16 int adding(a,b,c){
17 int e;
18 e = a+b+c;
19 return e;
20 }
21 int multiply(a,b,c){
22 int f = a*b*c;
23 return f;
24 }
//我用-q编译,我想打印变量的值(来自他们的地址)所以......
(gdb) disassemble main
0x080483ed <+9>: mov DWORD PTR [esp+0x2c],0x5
0x080483f5 <+17>: mov DWORD PTR [esp+0x28],0x6
0x080483fd <+25>: mov DWORD PTR [esp+0x24],0x7
0x08048405 <+33>: mov eax,DWORD PTR [esp+0x24] <code>
我在main / multiply / adds中添加了一些断点,然后我尝试执行以下操作。
我用过print $esp+0x24
和
(gdb) x/4d 0xbffff47c
但我没有得到正确答案。
我使用4d是因为我认为整数是4个字节(或者可能再次缺少某些东西),但结果不显示值5。 你能帮我么?谢谢,抱歉gdb的输出/格式不好..严重我不明白什么是错的
(gdb) print $esp+0x2c
$2 = (void *) 0xbffff494
(gdb) print $esp+0x28
$3 = (void *) 0xbffff490
(gdb) print $esp+0x24
$4 = (void *) 0xbffff48c
(gdb) x/d 0xbffff494
0xbffff494: -1208180748
(gdb) x/d 0xbffff490
0xbffff490: -1208179932
(gdb) x/d 0xbffff48c
0xbffff48c: 134513881
此次发生在main的第一个断点之后,实际上相同的值一直在所有断点中出现(除了main之前的那个...)
我发现的另一个有趣的事情是以下......我确信第一个值是垃圾。但是为什么它应该在打印实际值时将0x5视为地址?
Breakpoint 1, main () at functioncalling.c:10
10 a = 5;
(gdb) x/s a
0xb7fc9ff4: "|M\025"
(gdb) cont
Continuing.
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21 e = a+b+c;
(gdb) x/s a
0x5: <Address 0x5 out of bounds>
答案 0 :(得分:1)
我用-g
编译你的程序而没有优化,并在第11行之前设置了一个断点。我的堆栈地址与你的有点不同,考虑到各种各样的系统,这并不奇怪。
(gdb) print $esp+0x2c
$2 = (void *) 0xbffff44c
这是打印a
的地址。确认:
(gdb) print &a
$4 = (int *) 0xbffff44c
使用x/wd
显示十进制的4字节整数。
(gdb) x/wd $esp+0x2c
0xbffff44c: 5
x/4d
将显示从地址开始的4个值(4是重复计数)。如果在此省略大小字母w
,则x
命令将默认为先前使用的大小。
(gdb) x/4d $esp+0x2c
0xbffff44c: 5 134513856 0 -1073744680
有你的5.至于其他3个数字,它们是堆栈中的东西。
(gdb) x/4a $esp+0x2c
0xbffff44c: 0x5 0x80484c0 <__libc_csu_init> 0x0 0xbffff4d8
你的下一个问题:
我发现的另一个有趣的事情是以下......我确信第一个值是垃圾。但是为什么它应该在打印实际值时将0x5视为地址?
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21 e = a+b+c;
(gdb) x/s a
0x5: <Address 0x5 out of bounds>
x
命令,当程序的变量作为其参数时,检索其值并将其用作地址。 x/s a
表示检索a
中的值并将其用作NUL终止字符串的起始地址。如果a
类型为char *
且包含合适的值,则x/s
将打印合理的输出。要打印a
的实际值,请为x
命令指定参数&a
。
(gdb) x/wd &a
0xbffff44c: 5
这似乎违反直觉。只需考虑x
命令就像C语句printf(fmt, *(argument))
那样操作。 x
命令的参数几乎总是一个文字内存地址或涉及堆栈指针,基址指针或pc寄存器的地址表达式。