进程虚拟地址困惑

进程虚拟地址困惑_第1张图片

x86 32位CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。

段页式机制如下图。

进程虚拟地址困惑_第2张图片

虚拟内存地址 通过CPU特殊组件 还有页表进行映射到物理内存地址上

下面是页表功能, 以前我学习过页表 可以参考

Linux 64 页表,进程内存,大页

Linux_x86_64BIT内存管理与分布

进程虚拟地址困惑_第3张图片

64位进程后来没有了逻辑地址,下面学习BIN的技术小屋的时候,发现个疑问

进程虚拟地址困惑_第4张图片

那就是 进程的虚拟地址有规划代码段起始地址是: 0X000 000 0040 0000
内核地址空间也有地址规划!

进程虚拟地址困惑_第5张图片

进程虚拟地址困惑_第6张图片

什么问题呢? 就是 页表必须按规划的地址进行分配 比如说:
0X000 000 0040 0000 16进制变成2进制48位

0x000000000,000000000,000000100,000000000,00000000000

PMD 页目录偏移=100  换成10进制=4 前面3个位置被谁占了?
 

内存本来就精贵的资源,而且页表也占用内存,页表现在就变成了稀疏数组了.

相对于来说就是浪费了很多内存,前面3个数组下标 64位占用8个字节,就24个字节单位. 

我们程序运行过程中打印的变量地址, 函数地址,指针地址. 这些都是什么呢? 以前叫逻辑地址,现在被说成了虚拟地址.

那么这个地址是哪个部分? 还是两种不一样的东西,还是一样的东西不同的叫法, 确实让人着迷一段时间,期间访问很多大佬,视乎也没有个明确的说法.

继续深入学习LINUX内核文章时候,视乎感觉LINUX系统 不按程序的要求进行地址安排,0X000 000 0040 0000  这个地址虚拟化 不一定是 0040.

因为64位就一个段地址,基地址都是0!

进程虚拟地址困惑_第7张图片

进程自己的虚拟内存空间还有个边界, 分配的虚拟地址在边界范围之内,那么如何鉴定地址越界呢? 如果说地址是连续的,那么就好比较.

可虚拟地址格式 4个9位 是按照页表目录索引数字.

要么按照规划来分配页表, 就造成稀疏页表,浪费很多内存.

如果按照节约内存方式,搞紧凑页表,就得先来先分配,先来的在低地址 ,后来的就在高地址. 那边界感怎么搞?

所以这个事比较困惑! 虽然无关紧要, 可是用GCC语言开发非常容易地址越界,非法存取,野指针. 


#include 
#include 
#include 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int g=78;

int main(int argc, char *argv[])
{
   int i;
   printf("变量i的定义时地址是:%p\n", &i);
   i=32;
   printf("变量i赋值后的地址是:%p\n", &i);

   printf("全局静态变量G的地址: %p\n",&g);

  char *pChar;
  printf("pChar内存变量本身地址: %p\n",&pChar);
  pChar=(char*)malloc(10);
  printf("动态分配地址: %p\n",pChar);
  strcpy(pChar,"123456iii");
  printf("使用动态分配地址: %p\n",pChar);

 char cExit;
 printf("是否退出? Y/N");
 scanf("%c",&cExit);
 if (cExit=='Y')
        return 0;

}

上面这段C语言可以完整在CENTOS 编译通过,运行效果如下


[root@dsmart=>OTHER_C]$./Vmaddres.exe 
变量i的定义时地址是:0x7fffffffe04c
变量i赋值后的地址是:0x7fffffffe04c
全局静态变量G的地址: 0x601050
pChar内存变量本身地址: 0x7fffffffe040
动态分配地址: 0x602010
使用动态分配地址: 0x602010
是否退出? Y/Ny

变量i 的地址一直没有发生改变,按照虚拟内存假分配,通过实际使用中发生缺页中断来分配实际的物理内存

虚拟内存地址 低12位 也就是0:12位是实际物理内存地址... 

011111111,111111111,111111111,111111110,000001001100

因此小仙认为 在64位 程序里面看到的地址叫逻辑地址(兼容32位叫法),或者叫程序地址. 

程序地址 <==>进程虚拟地址 有个映射关系 或者数组来1:1对应.

静态读取可执行文件,发现有虚拟地址,物理地址,偏移量,文件大小,内存大小,权限,对齐等信息. 


[root@dsmart=>OTHER_C]$readelf -h Vmaddres.exe 
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x4004f0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6560 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28


[root@dsmart=>OTHER_C]$readelf -l Vmaddres.exe 

Elf file type is EXEC (Executable file)
Entry point 0x4004f0
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr           FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8  R E    8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c  R      1
   [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000 0x000000000000097c 0x000000000000097c  R E    200000
  LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e10 0x0000000000000244 0x0000000000000248  RW     200000
  DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e28 0x00000000000001d0 0x00000000000001d0  RW     8
  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000020 0x0000000000000020  R      4
  GNU_EH_FRAME   0x0000000000000850 0x0000000000400850 0x0000000000400850 0x0000000000000034 0x0000000000000034  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e10 0x00000000000001f0 0x00000000000001f0  R      1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .jcr .dynamic .got 


[root@dsmart=>OTHER_C]$readelf -S Vmaddres.exe 
There are 29 section headers, starting at offset 0x19a0:

Section Headers:
  [Nr] Name              Type             Address           Offset         Size              EntSize            Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400238  00000238       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .hash             HASH             0000000000400278  00000278       000000000000002c  0000000000000004   A       4     0     8
  [ 4] .dynsym           DYNSYM           00000000004002a8  000002a8       0000000000000090  0000000000000018   A       5     1     8
  [ 5] .dynstr           STRTAB           0000000000400338  00000338       000000000000005f  0000000000000000   A       0     0     1
  [ 6] .gnu.version      VERSYM           0000000000400398  00000398       000000000000000c  0000000000000002   A       4     0     2
  [ 7] .gnu.version_r    VERNEED          00000000004003a8  000003a8       0000000000000030  0000000000000000   A       5     1     8
  [ 8] .rela.dyn         RELA             00000000004003d8  000003d8       0000000000000018  0000000000000018   A       4     0     8
  [ 9] .rela.plt         RELA             00000000004003f0  000003f0       0000000000000078  0000000000000018  AI       4    22     8
  [10] .init             PROGBITS         0000000000400468  00000468       000000000000001a  0000000000000000  AX       0     0     4
  [11] .plt              PROGBITS         0000000000400490  00000490       0000000000000060  0000000000000010  AX       0     0     16
  [12] .text             PROGBITS         00000000004004f0  000004f0       0000000000000262  0000000000000000  AX       0     0     16
  [13] .fini             PROGBITS         0000000000400754  00000754       0000000000000009  0000000000000000  AX       0     0     4
  [14] .rodata           PROGBITS         0000000000400760  00000760       00000000000000ee  0000000000000000   A       0     0     8
  [15] .eh_frame_hdr     PROGBITS         0000000000400850  00000850       0000000000000034  0000000000000000   A       0     0     4
  [16] .eh_frame         PROGBITS         0000000000400888  00000888       00000000000000f4  0000000000000000   A       0     0     8
  [17] .init_array       INIT_ARRAY       0000000000600e10  00000e10       0000000000000008  0000000000000008  WA       0     0     8
  [18] .fini_array       FINI_ARRAY       0000000000600e18  00000e18       0000000000000008  0000000000000008  WA       0     0     8
  [19] .jcr              PROGBITS         0000000000600e20  00000e20       0000000000000008  0000000000000000  WA       0     0     8
  [20] .dynamic          DYNAMIC          0000000000600e28  00000e28       00000000000001d0  0000000000000010  WA       5     0     8
  [21] .got              PROGBITS         0000000000600ff8  00000ff8       0000000000000008  0000000000000008  WA       0     0     8
  [22] .got.plt          PROGBITS         0000000000601000  00001000       0000000000000040  0000000000000008  WA       0     0     8
  [23] .data             PROGBITS         0000000000601040  00001040       0000000000000014  0000000000000000  WA       0     0     8
  [24] .bss              NOBITS           0000000000601054  00001054       0000000000000004  0000000000000000  WA       0     0     1
  [25] .comment          PROGBITS         0000000000000000  00001054       000000000000003e  0000000000000001  MS       0     0     1
  [26] .symtab           SYMTAB           0000000000000000  00001098       0000000000000618  0000000000000018          27    45     8
  [27] .strtab           STRTAB           0000000000000000  000016b0       00000000000001ff  0000000000000000           0     0     1
  [28] .shstrtab         STRTAB           0000000000000000  000018af       00000000000000f1  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

上面列出的信息,搞不懂,基本是说把程序里面某些节,加载到指定内存上

进程虚拟地址困惑_第8张图片

linux中,nm用来列出目标文件的符号清单。

[root@dsmart=>OTHER_C]$nm -n Vmaddres.exe 
                 w __gmon_start__
                 U __isoc99_scanf@@GLIBC_2.7
                 U __libc_start_main@@GLIBC_2.2.5
                 U malloc@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000400468 T _init
00000000004004f0 T _start
0000000000400520 t deregister_tm_clones
0000000000400560 t register_tm_clones
00000000004005a0 t __do_global_dtors_aux
00000000004005c0 t frame_dummy
00000000004005e6 T main
00000000004006e0 T __libc_csu_init
0000000000400750 T __libc_csu_fini
0000000000400754 T _fini
0000000000400760 R _IO_stdin_used
0000000000400850 r __GNU_EH_FRAME_HDR
0000000000400978 r __FRAME_END__
0000000000600e10 t __frame_dummy_init_array_entry
0000000000600e10 t __init_array_start
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000600e18 t __init_array_end
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
0000000000600e28 d _DYNAMIC
0000000000601000 d _GLOBAL_OFFSET_TABLE_
0000000000601040 D __data_start
0000000000601040 W data_start
0000000000601048 D __dso_handle
0000000000601050 D g
0000000000601054 B __bss_start
0000000000601054 b completed.6904
0000000000601054 D _edata
0000000000601058 B _end
0000000000601058 D __TMC_END__

使用静态反汇编查看,代码段400468, 


[root@dsmart=>OTHER_C]$objdump -d Vmaddres.exe 

Vmaddres.exe:     file format elf64-x86-64


Disassembly of section .init:

0000000000400468 <_init>:
  400468:  48 83 ec 08            sub    $0x8,%rsp
  40046c:  48 8b 05 85 0b 20 00   mov    0x200b85(%rip),%rax        # 600ff8 <__gmon_start__>
  400473:  48 85 c0               test   %rax,%rax
  400476:  74 05                  je     40047d <_init+0x15>
  400478:  e8 43 00 00 00         callq  4004c0 <__gmon_start__@plt>
  40047d:  48 83 c4 08            add    $0x8,%rsp
  400481:  c3                     retq   

Disassembly of section .plt:

0000000000400490 <.plt>:
  400490:  ff 35 72 0b 20 00      pushq  0x200b72(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  400496:  ff 25 74 0b 20 00      jmpq   *0x200b74(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  40049c:  0f 1f 40 00            nopl   0x0(%rax)

00000000004004a0 :
  4004a0:  ff 25 72 0b 20 00      jmpq   *0x200b72(%rip)        # 601018 
  4004a6:  68 00 00 00 00         pushq  $0x0
  4004ab:  e9 e0 ff ff ff         jmpq   400490 <.plt>

00000000004004b0 <__libc_start_main@plt>:
  4004b0:  ff 25 6a 0b 20 00      jmpq   *0x200b6a(%rip)        # 601020 <__libc_start_main@GLIBC_2.2.5>
  4004b6:  68 01 00 00 00         pushq  $0x1
  4004bb:  e9 d0 ff ff ff         jmpq   400490 <.plt>

00000000004004c0 <__gmon_start__@plt>:
  4004c0:  ff 25 62 0b 20 00      jmpq   *0x200b62(%rip)        # 601028 <__gmon_start__>
  4004c6:  68 02 00 00 00         pushq  $0x2
  4004cb:  e9 c0 ff ff ff         jmpq   400490 <.plt>

00000000004004d0 :
  4004d0:  ff 25 5a 0b 20 00      jmpq   *0x200b5a(%rip)        # 601030 
  4004d6:  68 03 00 00 00         pushq  $0x3
  4004db:  e9 b0 ff ff ff         jmpq   400490 <.plt>

00000000004004e0 <__isoc99_scanf@plt>:
  4004e0:  ff 25 52 0b 20 00      jmpq   *0x200b52(%rip)        # 601038 <__isoc99_scanf@GLIBC_2.7>
  4004e6:  68 04 00 00 00         pushq  $0x4
  4004eb:  e9 a0 ff ff ff         jmpq   400490 <.plt>

Disassembly of section .text:

00000000004004f0 <_start>:
  4004f0:  31 ed                  xor    %ebp,%ebp
  4004f2:  49 89 d1               mov    %rdx,%r9
  4004f5:  5e                     pop    %rsi
  4004f6:  48 89 e2               mov    %rsp,%rdx
  4004f9:  48 83 e4 f0            and    $0xfffffffffffffff0,%rsp
  4004fd:  50                     push   %rax
  4004fe:  54                     push   %rsp
  4004ff:  49 c7 c0 50 07 40 00   mov    $0x400750,%r8
  400506:  48 c7 c1 e0 06 40 00   mov    $0x4006e0,%rcx
  40050d:  48 c7 c7 e6 05 40 00   mov    $0x4005e6,%rdi
  400514:  e8 97 ff ff ff         callq  4004b0 <__libc_start_main@plt>
  400519:  f4                     hlt    
  40051a:  66 0f 1f 44 00 00      nopw   0x0(%rax,%rax,1)

0000000000400520 :
  400520:  b8 5f 10 60 00         mov    $0x60105f,%eax
  400525:  55                     push   %rbp
  400526:  48 2d 58 10 60 00      sub    $0x601058,%rax
  40052c:  48 83 f8 0e            cmp    $0xe,%rax
  400530:  48 89 e5               mov    %rsp,%rbp
  400533:  76 1b                  jbe    400550 
  400535:  b8 00 00 00 00         mov    $0x0,%eax
  40053a:  48 85 c0               test   %rax,%rax
  40053d:  74 11                  je     400550 
  40053f:  5d                     pop    %rbp
  400540:  bf 58 10 60 00         mov    $0x601058,%edi
  400545:  ff e0                  jmpq   *%rax
  400547:  66 0f 1f 84 00 00 00   nopw   0x0(%rax,%rax,1)
  40054e:  00 00 
  400550:  5d                     pop    %rbp
  400551:  c3                     retq   
  400552:  0f 1f 40 00            nopl   0x0(%rax)
  400556:  66 2e 0f 1f 84 00 00   nopw   %cs:0x0(%rax,%rax,1)
  40055d:  00 00 00 

0000000000400560 :
  400560:  be 58 10 60 00         mov    $0x601058,%esi
  400565:  55                     push   %rbp
  400566:  48 81 ee 58 10 60 00   sub    $0x601058,%rsi
  40056d:  48 c1 fe 03            sar    $0x3,%rsi
  400571:  48 89 e5               mov    %rsp,%rbp
  400574:  48 89 f0               mov    %rsi,%rax
  400577:  48 c1 e8 3f            shr    $0x3f,%rax
  40057b:  48 01 c6               add    %rax,%rsi
  40057e:  48 d1 fe               sar    %rsi
  400581:  74 15                  je     400598 
  400583:  b8 00 00 00 00         mov    $0x0,%eax
  400588:  48 85 c0               test   %rax,%rax
  40058b:  74 0b                  je     400598 
  40058d:  5d                     pop    %rbp
  40058e:  bf 58 10 60 00         mov    $0x601058,%edi
  400593:  ff e0                  jmpq   *%rax
  400595:  0f 1f 00               nopl   (%rax)
  400598:  5d                     pop    %rbp
  400599:  c3                     retq   
  40059a:  66 0f 1f 44 00 00      nopw   0x0(%rax,%rax,1)

00000000004005a0 <__do_global_dtors_aux>:
  4005a0:  80 3d ad 0a 20 00 00   cmpb   $0x0,0x200aad(%rip)        # 601054 <_edata>
  4005a7:  75 11                  jne    4005ba <__do_global_dtors_aux+0x1a>
  4005a9:  55                     push   %rbp
  4005aa:  48 89 e5               mov    %rsp,%rbp
  4005ad:  e8 6e ff ff ff         callq  400520 
  4005b2:  5d                     pop    %rbp
  4005b3:  c6 05 9a 0a 20 00 01   movb   $0x1,0x200a9a(%rip)        # 601054 <_edata>
  4005ba:  f3 c3                  repz retq 
  4005bc:  0f 1f 40 00            nopl   0x0(%rax)

00000000004005c0 :
  4005c0:  bf 20 0e 60 00         mov    $0x600e20,%edi
  4005c5:  48 83 3f 00            cmpq   $0x0,(%rdi)
  4005c9:  75 05                  jne    4005d0 
  4005cb:  eb 93                  jmp    400560 
  4005cd:  0f 1f 00               nopl   (%rax)
  4005d0:  b8 00 00 00 00         mov    $0x0,%eax
  4005d5:  48 85 c0               test   %rax,%rax
  4005d8:  74 f1                  je     4005cb 
  4005da:  55                     push   %rbp
  4005db:  48 89 e5               mov    %rsp,%rbp
  4005de:  ff d0                  callq  *%rax
  4005e0:  5d                     pop    %rbp
  4005e1:  e9 7a ff ff ff         jmpq   400560 

00000000004005e6 
: 4005e6: 55 push %rbp 4005e7: 48 89 e5 mov %rsp,%rbp 4005ea: 48 83 ec 30 sub $0x30,%rsp 4005ee: 89 7d dc mov %edi,-0x24(%rbp) 4005f1: 48 89 75 d0 mov %rsi,-0x30(%rbp) 4005f5: 48 8d 45 fc lea -0x4(%rbp),%rax 4005f9: 48 89 c6 mov %rax,%rsi 4005fc: bf 68 07 40 00 mov $0x400768,%edi 400601: b8 00 00 00 00 mov $0x0,%eax 400606: e8 95 fe ff ff callq 4004a0 40060b: c7 45 fc 20 00 00 00 movl $0x20,-0x4(%rbp) 400612: 48 8d 45 fc lea -0x4(%rbp),%rax 400616: 48 89 c6 mov %rax,%rsi 400619: bf 90 07 40 00 mov $0x400790,%edi 40061e: b8 00 00 00 00 mov $0x0,%eax 400623: e8 78 fe ff ff callq 4004a0 400628: be 50 10 60 00 mov $0x601050,%esi 40062d: bf b8 07 40 00 mov $0x4007b8,%edi 400632: b8 00 00 00 00 mov $0x0,%eax 400637: e8 64 fe ff ff callq 4004a0 40063c: 48 8d 45 f0 lea -0x10(%rbp),%rax 400640: 48 89 c6 mov %rax,%rsi 400643: bf e0 07 40 00 mov $0x4007e0,%edi 400648: b8 00 00 00 00 mov $0x0,%eax 40064d: e8 4e fe ff ff callq 4004a0 400652: bf 0a 00 00 00 mov $0xa,%edi 400657: e8 74 fe ff ff callq 4004d0 40065c: 48 89 45 f0 mov %rax,-0x10(%rbp) 400660: 48 8b 45 f0 mov -0x10(%rbp),%rax 400664: 48 89 c6 mov %rax,%rsi 400667: bf 03 08 40 00 mov $0x400803,%edi 40066c: b8 00 00 00 00 mov $0x0,%eax 400671: e8 2a fe ff ff callq 4004a0 400676: 48 8b 45 f0 mov -0x10(%rbp),%rax 40067a: 48 ba 31 32 33 34 35 movabs $0x6969363534333231,%rdx 400681: 36 69 69 400684: 48 89 10 mov %rdx,(%rax) 400687: 66 c7 40 08 69 00 movw $0x69,0x8(%rax) 40068d: 48 8b 45 f0 mov -0x10(%rbp),%rax 400691: 48 89 c6 mov %rax,%rsi 400694: bf 1b 08 40 00 mov $0x40081b,%edi 400699: b8 00 00 00 00 mov $0x0,%eax 40069e: e8 fd fd ff ff callq 4004a0 4006a3: bf 39 08 40 00 mov $0x400839,%edi 4006a8: b8 00 00 00 00 mov $0x0,%eax 4006ad: e8 ee fd ff ff callq 4004a0 4006b2: 48 8d 45 ef lea -0x11(%rbp),%rax 4006b6: 48 89 c6 mov %rax,%rsi 4006b9: bf 4b 08 40 00 mov $0x40084b,%edi 4006be: b8 00 00 00 00 mov $0x0,%eax 4006c3: e8 18 fe ff ff callq 4004e0 <__isoc99_scanf@plt> 4006c8: 0f b6 45 ef movzbl -0x11(%rbp),%eax 4006cc: 3c 59 cmp $0x59,%al 4006ce: 75 07 jne 4006d7 4006d0: b8 00 00 00 00 mov $0x0,%eax 4006d5: eb 05 jmp 4006dc 4006d7: b8 00 00 00 00 mov $0x0,%eax 4006dc: c9 leaveq 4006dd: c3 retq 4006de: 66 90 xchg %ax,%ax 00000000004006e0 <__libc_csu_init>: 4006e0: 41 57 push %r15 4006e2: 41 89 ff mov %edi,%r15d 4006e5: 41 56 push %r14 4006e7: 49 89 f6 mov %rsi,%r14 4006ea: 41 55 push %r13 4006ec: 49 89 d5 mov %rdx,%r13 4006ef: 41 54 push %r12 4006f1: 4c 8d 25 18 07 20 00 lea 0x200718(%rip),%r12 # 600e10 <__frame_dummy_init_array_entry> 4006f8: 55 push %rbp 4006f9: 48 8d 2d 18 07 20 00 lea 0x200718(%rip),%rbp # 600e18 <__init_array_end> 400700: 53 push %rbx 400701: 4c 29 e5 sub %r12,%rbp 400704: 31 db xor %ebx,%ebx 400706: 48 c1 fd 03 sar $0x3,%rbp 40070a: 48 83 ec 08 sub $0x8,%rsp 40070e: e8 55 fd ff ff callq 400468 <_init> 400713: 48 85 ed test %rbp,%rbp 400716: 74 1e je 400736 <__libc_csu_init+0x56> 400718: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 40071f: 00 400720: 4c 89 ea mov %r13,%rdx 400723: 4c 89 f6 mov %r14,%rsi 400726: 44 89 ff mov %r15d,%edi 400729: 41 ff 14 dc callq *(%r12,%rbx,8) 40072d: 48 83 c3 01 add $0x1,%rbx 400731: 48 39 eb cmp %rbp,%rbx 400734: 75 ea jne 400720 <__libc_csu_init+0x40> 400736: 48 83 c4 08 add $0x8,%rsp 40073a: 5b pop %rbx 40073b: 5d pop %rbp 40073c: 41 5c pop %r12 40073e: 41 5d pop %r13 400740: 41 5e pop %r14 400742: 41 5f pop %r15 400744: c3 retq 400745: 90 nop 400746: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 40074d: 00 00 00 0000000000400750 <__libc_csu_fini>: 400750: f3 c3 repz retq Disassembly of section .fini: 0000000000400754 <_fini>: 400754: 48 83 ec 08 sub $0x8,%rsp 400758: 48 83 c4 08 add $0x8,%rsp 40075c: c3 retq

运行过程不退出,查看程序运行中的虚拟内存

[root@dsmart=>OTHER_C]$./Vmaddres.exe 
变量i的定义时地址是:0x7fffffffe04c
变量i赋值后的地址是:0x7fffffffe04c
全局静态变量G的地址: 0x601050
pChar内存变量本身地址: 0x7fffffffe040
动态分配地址: 0x602010
使用动态分配地址: 0x602010
是否退出? Y/N

另外个SSH窗口
[root@dsmart=>~]$ps -ef | grep Vmaddres.exe
root      9743 12107  0 15:27 pts/3    00:00:00 ./Vmaddres.exe
root      9771 31251  0 15:28 pts/1    00:00:00 grep --color Vmaddres.exe


查看进程MAPS
[root@dsmart=>~]$cat /proc/9743/maps
00400000-00401000 r-xp 00000000 fd:02 16520679                           /home/Project/OTHER_C/Vmaddres.exe
00600000-00601000 r--p 00000000 fd:02 16520679                           /home/Project/OTHER_C/Vmaddres.exe
00601000-00602000 rw-p 00001000 fd:02 16520679                           /home/Project/OTHER_C/Vmaddres.exe
00602000-00623000 rw-p 00000000 00:00 0                                  [heap]
7ffff7a0d000-7ffff7bd1000 r-xp 00000000 fd:00 37765873                   /usr/lib64/libc-2.17.so
7ffff7bd1000-7ffff7dd0000 ---p 001c4000 fd:00 37765873                   /usr/lib64/libc-2.17.so
7ffff7dd0000-7ffff7dd4000 r--p 001c3000 fd:00 37765873                   /usr/lib64/libc-2.17.so
7ffff7dd4000-7ffff7dd6000 rw-p 001c7000 fd:00 37765873                   /usr/lib64/libc-2.17.so
7ffff7dd6000-7ffff7ddb000 rw-p 00000000 00:00 0 
7ffff7ddb000-7ffff7dfd000 r-xp 00000000 fd:00 37765866                   /usr/lib64/ld-2.17.so
7ffff7fea000-7ffff7fed000 rw-p 00000000 00:00 0 
7ffff7ff7000-7ffff7ffa000 rw-p 00000000 00:00 0 
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00021000 fd:00 37765866                   /usr/lib64/ld-2.17.so
7ffff7ffd000-7ffff7ffe000 rw-p 00022000 fd:00 37765866                   /usr/lib64/ld-2.17.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

变量i的定义时地址是:0x7fffffffe04c 居然在上面最后地址范围内.

7ffffffde000-7ffffffff000 rw-p 0000000000:000     [stack]

意思如下:


开始-结束            00400000-00401000 
访问权限              r-xp
偏移                  00000000
主设备号:次设备号    fd:02
i节点                 16520679
文件                  /home/Project/OTHER_C/Vmaddres.exe

前三段虚拟内存地址范围,跟静态地址一样!

使用GDB 运行反汇编

对C程序添加调试信息 -g 进行编译

[root@dsmart=>OTHER_C]$gdb vmaddres.exe 
下面这行表示读到额调试信息
Reading symbols from /home/Project/OTHER_C/vmaddres.exe...done.
查看源码
(gdb) list   
1  #include 
2  #include 
3  #include 
4  /* run this program using the console pauser or add your own getch, system("pause") or input loop */
5  int g=78;
6  
7  int main(int argc, char *argv[])
8  {
9     int i;
10     printf("变量i的定义时地址是:%p\n", &i);
在第一行打上断点,然后运行
(gdb) b 1
Breakpoint 1 at 0x4005f5: file VmAddres.c, line 1.
(gdb) run
Starting program: /home/Project/OTHER_C/vmaddres.exe 

Breakpoint 1, main (argc=1, argv=0x7fffffffe128) at VmAddres.c:10
10     printf("变量i的定义时地址是:%p\n", &i);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64

输入反汇编命令

(gdb) disas
Dump of assembler code for function main:
   0x00000000004005e6 <+0>:  push   %rbp
   0x00000000004005e7 <+1>:  mov    %rsp,%rbp
   0x00000000004005ea <+4>:  sub    $0x30,%rsp
   0x00000000004005ee <+8>:  mov    %edi,-0x24(%rbp)
   0x00000000004005f1 <+11>:  mov    %rsi,-0x30(%rbp)
=> 0x00000000004005f5 <+15>:  lea    -0x4(%rbp),%rax
   0x00000000004005f9 <+19>:  mov    %rax,%rsi
   0x00000000004005fc <+22>:  mov    $0x400768,%edi
   0x0000000000400601 <+27>:  mov    $0x0,%eax
   0x0000000000400606 <+32>:  callq  0x4004a0 
   0x000000000040060b <+37>:  movl   $0x20,-0x4(%rbp)
   0x0000000000400612 <+44>:  lea    -0x4(%rbp),%rax
   0x0000000000400616 <+48>:  mov    %rax,%rsi
   0x0000000000400619 <+51>:  mov    $0x400790,%edi
   0x000000000040061e <+56>:  mov    $0x0,%eax
   0x0000000000400623 <+61>:  callq  0x4004a0 
   0x0000000000400628 <+66>:  mov    $0x601050,%esi
   0x000000000040062d <+71>:  mov    $0x4007b8,%edi
   0x0000000000400632 <+76>:  mov    $0x0,%eax
   0x0000000000400637 <+81>:  callq  0x4004a0 
   0x000000000040063c <+86>:  lea    -0x10(%rbp),%rax
   0x0000000000400640 <+90>:  mov    %rax,%rsi
   0x0000000000400643 <+93>:  mov    $0x4007e0,%edi
   0x0000000000400648 <+98>:  mov    $0x0,%eax
   0x000000000040064d <+103>:  callq  0x4004a0 
   0x0000000000400652 <+108>:  mov    $0xa,%edi
   0x0000000000400657 <+113>:  callq  0x4004d0 
   0x000000000040065c <+118>:  mov    %rax,-0x10(%rbp)
   0x0000000000400660 <+122>:  mov    -0x10(%rbp),%rax
   0x0000000000400664 <+126>:  mov    %rax,%rsi
   0x0000000000400667 <+129>:  mov    $0x400803,%edi
   0x000000000040066c <+134>:  mov    $0x0,%eax
   0x0000000000400671 <+139>:  callq  0x4004a0 
   0x0000000000400676 <+144>:  mov    -0x10(%rbp),%rax
   0x000000000040067a <+148>:  movabs $0x6969363534333231,%rdx
   0x0000000000400684 <+158>:  mov    %rdx,(%rax)
   0x0000000000400687 <+161>:  movw   $0x69,0x8(%rax)
   0x000000000040068d <+167>:  mov    -0x10(%rbp),%rax
   0x0000000000400691 <+171>:  mov    %rax,%rsi
   0x0000000000400694 <+174>:  mov    $0x40081b,%edi
   0x0000000000400699 <+179>:  mov    $0x0,%eax
   0x000000000040069e <+184>:  callq  0x4004a0 
   0x00000000004006a3 <+189>:  mov    $0x400839,%edi
   0x00000000004006a8 <+194>:  mov    $0x0,%eax
   0x00000000004006ad <+199>:  callq  0x4004a0 
   0x00000000004006b2 <+204>:  lea    -0x11(%rbp),%rax
   0x00000000004006b6 <+208>:  mov    %rax,%rsi
   0x00000000004006b9 <+211>:  mov    $0x40084b,%edi
   0x00000000004006be <+216>:  mov    $0x0,%eax
   0x00000000004006c3 <+221>:  callq  0x4004e0 <__isoc99_scanf@plt>
   0x00000000004006c8 <+226>:  movzbl -0x11(%rbp),%eax
   0x00000000004006cc <+230>:  cmp    $0x59,%al
   0x00000000004006ce <+232>:  jne    0x4006d7 
   0x00000000004006d0 <+234>:  mov    $0x0,%eax
   0x00000000004006d5 <+239>:  jmp    0x4006dc 
   0x00000000004006d7 <+241>:  mov    $0x0,%eax
   0x00000000004006dc <+246>:  leaveq 
   0x00000000004006dd <+247>:  retq   
End of assembler dump.

跟静态反汇编OBJDUMP  0x00000000004005e6 一致!

最后很大可能是 64程序逻辑地址,就是虚拟地址,也是进程虚拟地址,也是按照页表格式构成的虚拟地址. 那么物理地址偏移量,可能大概率是虚拟地址4K页,页内偏移量.

很大可能页表是稀疏的,存在很多空洞PTE 这类浪费内存的现象.

本文没有得出精准的答案,只是看了那么多公号文,问了些大佬,大佬也没有给出明确的答案

我讲东,他们讲西,不在一个频道上. 他们不理解我的疑惑, 也许只能去看,去调试LINUX 内核代码,看LINUX如何加载可执行文件,给它分配虚拟内存地址空间! 

喜欢可以扫描上面的公众号二维码,优先观看

你可能感兴趣的:(linux,汇编,c++)