首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >汇编:C程序设计中变量的内存地址

汇编:C程序设计中变量的内存地址
EN

Stack Overflow用户
提问于 2017-07-02 03:15:33
回答 1查看 1.4K关注 0票数 5

这是我的C代码

代码语言:javascript
复制
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

这是标准输出

代码语言:javascript
复制
C:\Codes>test
+-----+-------+---------+----------+
| Var | Dec   | Hex     | Address  |
+-----+-------+---------+----------+
|  a  | 12345 | 0x3039  | 0022FF4C |
|  b  | 74565 | 0x12345 | 0022FF48 |
+-----+-------+---------+----------+

这就是我在GDB上看到的

代码语言:javascript
复制
(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)

变量ab的地址应该分别位于0x22ff4c0x22ff48

代码语言:javascript
复制
(gdb) print &a
$1 = (int *) 0x22ff4c

(gdb) print &b
$2 = (int *) 0x22ff48

但是,如果您查看以下GDB反汇编输出,地址不是0x22ff4c & 0x22ff48,而是0x0040134e & 0x00401356

代码语言:javascript
复制
   0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
   0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

我也在x32dbg上调试过这个,但是也得到了相同的地址。

我在这里很困惑。如果0x0040134e0x00401356不是变量ab的内存地址,它们是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-02 03:40:41

代码语言:javascript
复制
0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

不,0x0040134e0x00401356不是变量ab的地址。相反,它们是代码中指令的地址,即指令指针IPab在以下行中初始化:

代码语言:javascript
复制
0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

这里,ab的地址分别是esp+0x1cesp+0x18,其中esp堆栈指针。作为地址,您将得到0x22ff4c0x22ff48,您可以很容易地从这两个地址中扣除当前的esp0x22ff4c - 0x1c

请注意,这个答案忽略了操作系统的底层虚拟内存管理或其他相关内存管理问题,即在大多数体系结构中,0x22ff4c0x22ff48将是虚拟内存地址,而不是您的内存的真实物理地址。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44867145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档