Linux逻辑地址与物理地址的key point

本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/32697735

以下的一段代码:

#include <stdio.h>
greeting()
{
printf("Hello, world!\n");
}
main()
{
greeting();
}

经过gcc、ld(链接、编译)之后,生成一个elf可执行文件,再使用objdump处理,生成的反汇编代码如下:

08048368 <greeting>:
8048368: 55 push %ebp
8048369: 89 e5 mov %esp,%ebp
804836b: 83 ec 08 sub $0x8,%esp
804836e: 83 ec 0c sub $0xc,%esp
8048371: 68 84 84 04 08 push $0x8048484
8048376: e8 35 ff ff ff call 80482b0 <[email protected]>
804837b: 83 c4 10 add $0x10,%esp
804837e: c9 leave
804837f: c3 ret
08048380 <main>:
8048380: 55 push %ebp
8048381: 89 e5 mov %esp,%ebp
8048383: 83 ec 08 sub $0x8,%esp
8048386: 83 e4 f0 and $0xfffffff0,%esp
8048389: b8 00 00 00 00 mov $0x0,%eax
804838e: 83 c0 0f add $0xf,%eax
8048391: 83 c0 0f add $0xf,%eax
8048394: c1 e8 04 shr $0x4,%eax
8048397: c1 e0 04 shl $0x4,%eax
804839a: 29 c4 sub %eax,%esp
804839c: e8 c7 ff ff ff call 8048368 <greeting>
80483a1: c9 leave
80483a2: c3 ret
80483a3: 90 nop

注意看greeting这个函数,的逻辑地址,现在是8048368。

基础差一些的同学,应该震惊了!

源代码在编译的时候,就能生成一个具体的逻辑地址!

试想一下,我们的Linux可以编译出成千上万个ELF文件,每一个文件中的地址都是有可能重复的,那么,不会冲突吗?

嘿嘿。

如果你有这个疑问,那么,说明,对Unix传统的copy-on-write机制还是没有理解透彻。

想要理解这个知识点,只需关注如下3点:

1,Linux的用户进程在虚拟地址上(或者线性地址,在Linux里,这两个概念没有区别)是完全独立的,连页目录都独立,而不是水平切割。

2,Linux里每个用户进程的虚拟地址、页目录,都是在fork + exec时,才会相应生成的。

3,虚拟地址到物理地址的转换。

note:本文有参考《Linux内核源代码情景分析》

Linux逻辑地址与物理地址的key point

时间: 2024-12-08 08:45:25

Linux逻辑地址与物理地址的key point的相关文章

Linux从逻辑地址到物理地址

转自:http://blog.chinaunix.net/uid-24774106-id-3427836.html 我们都知道,动态共享库里面的函数的共享的,这也是动态库的优势所在,就是节省内存.C 编译出来的可执行文件几乎都会用到libc的库,假如没有这个共享的技术,每个可执行文件都要占一份libc库的内存,这将是极大的内存浪费. 可是一直没搞明白,怎么样才能证明共享库里面函数的地址在物理内存层面是同一份?其实,这个问题的本质是程序里面的逻辑地址和物理内存地址之间是怎样映射的,说的再赤裸裸一点

逻辑地址、物理地址、线性地址

逻辑地址(Logical Address) 是指由程序产生的与段相关的偏移地址部分.例如,你在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址,不和绝对物理地址相干.只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换):逻辑也就是在Intel 保护模式下程序执行代码段限长内的偏移地址(假定代码段.数据段如果完全一样).应用程序员仅需与逻辑地址打交道,而分段和分页机制对您来说是

内存的段式管理和页式管理,逻辑地址-虚拟地址-物理地址

windowsx86内存管理 1.物理地址(physical address) 用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应. ——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样.所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,

逻辑地址与物理地址

逻辑地址(Logical Address) 是指由程序产生的与段相关的偏移地址部分.例如,你在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址,不和绝对物理地址相干.只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换):逻辑也就是在Intel 保护模式下程序执行代码段限长内的偏移地址(假定代码段.数据段如果完全一样).应用程序员仅需与逻辑地址打交道,而分段和分页机制对您来说是

Linux虚拟地址和物理地址的映射

?背景 一般情况下,Linux系统中,进程的4GB内存空间被划分成为两个部分------用户空间和内核空间,大小分别为0~3G,3~4G.用户进程通常情况下,只能访问用户空间的虚拟地址,不能访问到内核空间.每个进程的用户空间都是完全独立.互不相干的,用户进程各自有不同的页表.而内核空间是由内核负责映射,它并不会跟着进程改变,是固定的.内核空间地址有自己对应的页表,内核的虚拟空间独立于其他程序.3~4G之间的内核空间中,从低地址到高地址依次为:系统物理内存映射区-隔离带-vmalloc虚拟内存分配

内存管理笔记(分页,分段,逻辑地址,物理地址)【转】

本文转载自:http://www.cnblogs.com/felixfang/p/3420462.html 1. 物理地址和逻辑地址 物理地址:加载到内存地址寄存器中的地址,内存单元的真正地址.在前端总线上传输的内存地址都是物理内存地址,编号从0开始一直到可用物理内存的最高端.这些数字被北桥(Nortbridge chip)映射到实际的内存条上.物理地址是明确的.最终用在总线上的编号,不必转换,不必分页,也没有特权级检查(no translation, no paging, no privile

Linux 下面对物理地址的访问

参考链接:http://zhuhaibobb.blog.163.com/blog/static/2744006720101049030606/ Linux内核提供了/dev/mem驱动,提供了一种直接访问内存物理地址的方法,具体实施有两种方法,一是设备驱动,二是系统调用的方法. /dev/mem驱动的源文件在drivers/char/mem.c中.这个文件还生成了一些常用的字符设备驱动,表现为/dev/zero,/dev/null等一些特殊的字符设备驱动.cat /dev/mem时,显示的是所有

登录远程Linux服务器:报Host key verification failed错误

远程Linux服务器,报Host key verification failed错误.问题:使用其他电脑登录远程Linux服务器,可以登录,但其中一台电脑登录时报该错误.原因:是因为登录服务器时主机会把它的服务器登录标识证书记录下来,下次登录时会去比对之前的记录,由于系统重装,标识变了导致不能继续登录.解决:在客户端执行命令:ssh-keygen -R 要登录的服务器ip 错误详情和解决: LOVE:~ han$ ssh [email protected] @@@@@@@@@@@@@@@@@@@

linux内存管理---物理地址、线性地址、虚拟地址、逻辑地址之间的转换

linux内存管理---虚拟地址.逻辑地址.线性地址.物理地址的区别(一) 这篇文章中介绍了四个名词的概念,下面针对四个地址的转换进行分析 CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步(如下图): 首先,将给定一个逻辑地址(其实是段内偏移量,这个一定要理解!!!),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址, 其次,再利用其页式内存管理单元,转换为最终物理地址. 这样做两次转换,的确是非常麻烦而且没有必要的,因为直接可以把线性地址抽像给进程.之所以这样冗余