您的位置:首页 > 运维架构 > Linux

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

2015-11-08 01:53 549 查看
以下的一段代码:
#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 <printf@plt>
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内核源代码情景分析》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: