简体   繁体   English

汇编:C编程中变量的内存地址

[英]Assembly: Memory address of variables in C Programming

This is my C code 这是我的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

And this is the standard output 这是标准输出

C:\Codes>test
+-----+-------+---------+----------+
| Var | Dec   | Hex     | Address  |
+-----+-------+---------+----------+
|  a  | 12345 | 0x3039  | 0022FF4C |
|  b  | 74565 | 0x12345 | 0022FF48 |
+-----+-------+---------+----------+

This is what I'm seeing in GDB 这就是我在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)

The address for variables a & b is supposed to be at 0x22ff4c & 0x22ff48 respectively 变量ab的地址分别应为0x22ff4c0x22ff48

(gdb) print &a
$1 = (int *) 0x22ff4c

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

However, if you look at the following GDB disassemble output, the address was not 0x22ff4c & 0x22ff48 , but 0x0040134e & 0x00401356 但是,如果你看下面的GDB反汇编输出,地址不是0x22ff4c0x22ff48 ,而是0x0040134e0x00401356

   0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
   0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

I've also debug this on x32dbg but getting the same address too. 我也在x32dbg上调试了这个,但也得到了相同的地址。 x32dbg

I'm confused here. 我在这里很困惑。 What was the 0x0040134e & 0x00401356 if they are not the memory addresses for variables a & b ? 如果它们不是变量ab的内存地址,那么0x0040134e0x00401356是什么?

0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

No, 0x0040134e and 0x00401356 are not addresses for variables a and b . 不, 0x0040134e0x00401356不是变量ab地址。 Instead they are address of the instruction in code, ie instruction pointer IP . 相反,它们是代码中指令的地址,即指令指针IP a and b are initialized in these lines: ab在这些行中初始化:

0x0040134e <+14>:    mov    DWORD PTR [esp+0x1c],0x3039
0x00401356 <+22>:    mov    DWORD PTR [esp+0x18],0x12345

Here the address of a and b are esp+0x1c and esp+0x18 respectively where esp is the stack pointer . 这里ab的地址分别是esp+0x1cesp+0x18 ,其中esp堆栈指针 As address you are getting 0x22ff4c and 0x22ff48 from which you can easily deduct that current esp is 0x22ff4c - 0x1c . 作为地址,您将获得0x22ff4c0x22ff48 ,您可以从中轻松扣除当前esp0x22ff4c - 0x1c

Please note the this answer ignores the underlying virtual memory management or other related memory management matters of operating system, ie on most architecture 0x22ff4c and 0x22ff48 will be virtual memory address, not the real physical address of your RAM. 请注意,这个答案忽略了操作系统的底层虚拟内存管理或其他相关内存管理问题,即在大多数架构上, 0x22ff4c0x22ff48将是虚拟内存地址,而不是RAM的实际物理地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM