这是我的C代码
C:\Codes>gdb test -q
Reading symbols from C:\Codes\test.exe...done.
(gdb) list 1,15
1 #include<stdio.h>
2
3 int main()
4 {
5 int a = 12345;
6 int b = 0x12345;
7 printf("+-----+-------+---------+----------+\n");
8 printf("| Var | Dec | Hex | Address |\n");
9 printf("+-----+-------+---------+----------+\n");
10 printf("| a | %d | 0x%x | %p |\n",a,a,&a);
11 printf("| b | %d | 0x%x | %p |\n",b,b,&b);
12 printf("+-----+-------+---------+----------+\n");
13
14 return 0;
15 }
(gdb) set disassembly-flavor intel
这是标准输出
C:\Codes>test
+-----+-------+---------+----------+
| Var | Dec | Hex | Address |
+-----+-------+---------+----------+
| a | 12345 | 0x3039 | 0022FF4C |
| b | 74565 | 0x12345 | 0022FF48 |
+-----+-------+---------+----------+
这就是我在GDB中看到的
(gdb) break 7
Breakpoint 1 at 0x40135e: file test.c, line 7.
(gdb) run
Starting program: C:\Codes/test.exe
[New Thread 4044.0xab0]
Breakpoint 1, main () at test.c:7
7 printf("+-----+-------+---------+----------+\n");
(gdb) disassemble
Dump of assembler code for function main:
0x00401340 <+0>: push ebp
0x00401341 <+1>: mov ebp,esp
0x00401343 <+3>: and esp,0xfffffff0
0x00401346 <+6>: sub esp,0x20
0x00401349 <+9>: call 0x401990 <__main>
0x0040134e <+14>: mov DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>: mov DWORD PTR [esp+0x18],0x12345
=> 0x0040135e <+30>: mov DWORD PTR [esp],0x403024
0x00401365 <+37>: call 0x401c00 <puts>
0x0040136a <+42>: mov DWORD PTR [esp],0x40304c
0x00401371 <+49>: call 0x401c00 <puts>
0x00401376 <+54>: mov DWORD PTR [esp],0x403024
0x0040137d <+61>: call 0x401c00 <puts>
0x00401382 <+66>: mov edx,DWORD PTR [esp+0x1c]
0x00401386 <+70>: mov eax,DWORD PTR [esp+0x1c]
0x0040138a <+74>: lea ecx,[esp+0x1c]
0x0040138e <+78>: mov DWORD PTR [esp+0xc],ecx
0x00401392 <+82>: mov DWORD PTR [esp+0x8],edx
0x00401396 <+86>: mov DWORD PTR [esp+0x4],eax
0x0040139a <+90>: mov DWORD PTR [esp],0x403071
0x004013a1 <+97>: call 0x401c08 <printf>
0x004013a6 <+102>: mov edx,DWORD PTR [esp+0x18]
0x004013aa <+106>: mov eax,DWORD PTR [esp+0x18]
0x004013ae <+110>: lea ecx,[esp+0x18]
0x004013b2 <+114>: mov DWORD PTR [esp+0xc],ecx
0x004013b6 <+118>: mov DWORD PTR [esp+0x8],edx
0x004013ba <+122>: mov DWORD PTR [esp+0x4],eax
0x004013be <+126>: mov DWORD PTR [esp],0x40308c
0x004013c5 <+133>: call 0x401c08 <printf>
0x004013ca <+138>: mov DWORD PTR [esp],0x403024
0x004013d1 <+145>: call 0x401c00 <puts>
0x004013d6 <+150>: mov eax,0x0
0x004013db <+155>: leave
0x004013dc <+156>: ret
End of assembler dump.
(gdb)
变量地址a
&amp; b
应该在0x22ff4c
&amp;分别为0x22ff48
(gdb) print &a
$1 = (int *) 0x22ff4c
(gdb) print &b
$2 = (int *) 0x22ff48
但是,如果您查看以下GDB反汇编输出,则地址不是0x22ff4c
&amp; 0x22ff48
,0x0040134e
&amp; 0x00401356
0x0040134e <+14>: mov DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>: mov DWORD PTR [esp+0x18],0x12345
我在这里感到很困惑。什么是0x0040134e
&amp; 0x00401356
如果它们不是变量a
&amp;的内存地址b
?
答案 0 :(得分:8)
0x0040134e <+14>: mov DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>: mov DWORD PTR [esp+0x18],0x12345
不,0x0040134e
和0x00401356
不是变量a
和b
的地址。相反,它们是代码中指令的地址,即instruction pointer IP。 a
和b
在以下行中初始化:
0x0040134e <+14>: mov DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>: mov DWORD PTR [esp+0x18],0x12345
此处a
和b
的地址分别为esp+0x1c
和esp+0x18
,其中esp
为stack pointer。作为地址,您将获得0x22ff4c
和0x22ff48
,您可以从中轻松扣除当前esp
为0x22ff4c - 0x1c
。
请注意,这个答案忽略了操作系统的底层虚拟内存管理或其他相关内存管理问题,即大多数架构0x22ff4c
和0x22ff48
将是虚拟内存地址,而不是真实的物理地址你的RAM。