第二章 内存寻址
2.1 内存管理之内存寻址
图灵机->冯诺依曼体系结构
X86寻址的不同时期
8位(8080绝对地址)->16位(8086,段机制,实模式)->24位(80286,保护模式)->32位(80386,保护模式下可达4GB)->64位
- 实模式与保护模式寄存器的对比
- 保护模式下的页表寄存器
- 控制寄存器
Linux内核中的C与汇编
C语言->GNU的扩展C
汇编语言->AT&T
C语言中嵌入汇编语言->GCC嵌入式汇编
参考资料
《深入理解Linux内核》第三版第二章
《Intel 64 and IA-32 Architectures Software Developer Manuals》
2.2保护模式下的段机制
- 简单的“Hello World”程序
#incldue <stdio.h>
int main(void){
printf("Hello,World!\n");
return 0;
}
- 程序的编译、汇编、链接与装载
1.预处理
gcc -E hello.c -o hello.i
2.编译
gcc -S hello.i -o hello.s
3.汇编
gcc -c hello.s -o hello.o
4.链接
gcc hello.o -o hello
5.装载与执行
./hello
6.反汇编
objdump -d hello>log.txt(将反汇编的结果重定向,保存到log.txt中)
文件:待审核通过之后添加链接地址
最左边为虚拟地址,中间为指令码,右侧为AT&T汇编指令 - CPU访问虚拟地址:
- MMU的地址转换
- 分段机制
1.段描述符表
段号描述的是虚拟地址空间段的编号
基地址是线性空间中段的起始地址
- 段描述符结构
- 保护模式下段寄存器中存放什么?
索引or段号,这里的段寄存器也叫选择符,即从描述表中选择某个段。
RPL:表示请求者的特权级。
TI:Table Index表明段描述符是在全局还是局部描述符表中。
保护模式下的特权级:0~3,Linux中只使用:0-内核态,3-用户态 - 保护模式下的其他描述符表
GDT全局描述符表
IDT中断描述符表
LDT局部描述符表 - Linux中的段
线性地址 = 段的起始地址 + 偏移量
Linux在启动的过程中设置了段寄存器的值和全局描述表GDT的内容:
#define __KERNEL_CS 0x10
#define __KERNEL_DS 0x18
#define __USER_CS 0x23
#define __USER_DS 0x2B