进程虚拟地址困惑

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

段页式机制如下图。

图片

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

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

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

Linux_x86_64BIT内存管理与分布

图片

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

图片

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

图片

图片

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

图片

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

可虚拟地址格式 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/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)

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

图片

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/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 <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如何加载可执行文件,给它分配虚拟内存地址空间! 

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

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值