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

段页式机制如下图。

进程虚拟地址困惑_虚拟地址

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

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

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

Linux_x86_64BIT内存管理与分布

进程虚拟地址困惑_虚拟地址_02

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

进程虚拟地址困惑_linux_03

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

进程虚拟地址困惑_linux_04

进程虚拟地址困惑_页表_05

什么问题呢? 就是 页表必须按规划的地址进行分配 比如说:
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!

进程虚拟地址困惑_页表_06

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

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

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

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

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 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/.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)

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

进程虚拟地址困惑_汇编_07

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 <printf@plt>:
  4004a0:  ff 25 72 0b 20 00      jmpq   *0x200b72(%rip)        # 601018 <printf@GLIBC_2.2.5>
  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 <malloc@plt>:
  4004d0:  ff 25 5a 0b 20 00      jmpq   *0x200b5a(%rip)        # 601030 <malloc@GLIBC_2.2.5>
  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 <deregister_tm_clones>:
  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 <deregister_tm_clones+0x30>
  400535:  b8 00 00 00 00         mov    $0x0,%eax
  40053a:  48 85 c0               test   %rax,%rax
  40053d:  74 11                  je     400550 <deregister_tm_clones+0x30>
  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 <register_tm_clones>:
  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 <register_tm_clones+0x38>
  400583:  b8 00 00 00 00         mov    $0x0,%eax
  400588:  48 85 c0               test   %rax,%rax
  40058b:  74 0b                  je     400598 <register_tm_clones+0x38>
  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 <deregister_tm_clones>
  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 <frame_dummy>:
  4005c0:  bf 20 0e 60 00         mov    $0x600e20,%edi
  4005c5:  48 83 3f 00            cmpq   $0x0,(%rdi)
  4005c9:  75 05                  jne    4005d0 <frame_dummy+0x10>
  4005cb:  eb 93                  jmp    400560 <register_tm_clones>
  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 <frame_dummy+0xb>
  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 <register_tm_clones>

00000000004005e6 <main>:
  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 <printf@plt>
  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 <printf@plt>
  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 <printf@plt>
  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 <printf@plt>
  400652:  bf 0a 00 00 00         mov    $0xa,%edi
  400657:  e8 74 fe ff ff         callq  4004d0 <malloc@plt>
  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 <printf@plt>
  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 <printf@plt>
  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 <printf@plt>
  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 <main+0xf1>
  4006d0:  b8 00 00 00 00         mov    $0x0,%eax
  4006d5:  eb 05                  jmp    4006dc <main+0xf6>
  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/
7ffff7bd1000-7ffff7dd0000 ---p 001c4000 fd:00 37765873                   /usr/lib64/
7ffff7dd0000-7ffff7dd4000 r--p 001c3000 fd:00 37765873                   /usr/lib64/
7ffff7dd4000-7ffff7dd6000 rw-p 001c7000 fd:00 37765873                   /usr/lib64/
7ffff7dd6000-7ffff7ddb000 rw-p 00000000 00:00 0 
7ffff7ddb000-7ffff7dfd000 r-xp 00000000 fd:00 37765866                   /usr/lib64/
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/
7ffff7ffd000-7ffff7ffe000 rw-p 00022000 fd:00 37765866                   /usr/lib64/
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 <stdio.h>
2  #include <stdlib.h>
3  #include <string.h>
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 <printf@plt>
   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 <printf@plt>
   0x0000000000400628 <+66>:  mov    $0x601050,%esi
   0x000000000040062d <+71>:  mov    $0x4007b8,%edi
   0x0000000000400632 <+76>:  mov    $0x0,%eax
   0x0000000000400637 <+81>:  callq  0x4004a0 <printf@plt>
   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 <printf@plt>
   0x0000000000400652 <+108>:  mov    $0xa,%edi
   0x0000000000400657 <+113>:  callq  0x4004d0 <malloc@plt>
   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 <printf@plt>
   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 <printf@plt>
   0x00000000004006a3 <+189>:  mov    $0x400839,%edi
   0x00000000004006a8 <+194>:  mov    $0x0,%eax
   0x00000000004006ad <+199>:  callq  0x4004a0 <printf@plt>
   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 <main+241>
   0x00000000004006d0 <+234>:  mov    $0x0,%eax
   0x00000000004006d5 <+239>:  jmp    0x4006dc <main+246>
   0x00000000004006d7 <+241>:  mov    $0x0,%eax
   0x00000000004006dc <+246>:  leaveq 
   0x00000000004006dd <+247>:  retq   
End of assembler dump.

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

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

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

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

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