一.存储程序计算机工作原理:
冯诺依曼体系结构:即存储程序计算机;
从物理结构上来描述: CPU中的IP寄存器,通过总线获取内存中CS(代码段)的一条指令来执行;IP自增1;取下一条指令;
ABI:程序二进制接口;程序指令与CPU的接口;
在X86,32位计算机上,EIP总是指向一条即将执行的指令;EIP可以自增1;该1不是指字节或者32个字节;是指一条指令;每条指令占的存储空间可能不同;
同时,EIP还会被其他指令给修改;比如call; ret; jmp; conditional jmp(条件跳转)等指令修改;
(1)X86中的CPU的寄存器
AH AL AX(16位寄存器) EAX(32位寄存器) RAX(64位寄存器) 累加寄存器
BX EBX 基地址寄存器
CX ECX 计数寄存器
DX EDX 数据寄存器
EBP 堆栈基指针
ESI 变址寄存器
EDI 变址寄存器
ESP 堆栈顶指针
CS 代码段寄存器
DS 数据段寄存器
ES 附加数据段寄存器
SS 堆栈段寄存器
FS 附加数据段寄存器
GS 附加数据段寄存器
(2)计算机汇编指令(AT&T):
b,w,l,q分别代表8位,16位,32位和64位;目标操作数在源操作数的右边;
movl %eax, %edx 相当于 edx = eax; 寄存器寻址 (和内存无关)
movl $0x123,%edx 相当于edx = 0x123 立即寻址(和内存无关)
movl 0x123, %edx 相当于edx = *(int32_t*)0x123 直接寻址
movl (%ebx), %edx 相当于edx = *(int32_t*)ebx 间接寻址
movl 4(%ebx), %edx 相当于edx = *(int32_t*)(ebx + 4) 变址寻址
pushl %eax ==> subl $4, %esp 堆栈向下增长
movl %eax, (%esp)
popl %eax ==> movl (%esp), %eax
addl $4, %esp
call 0x12345 ==> pushl %eip (伪指令,程序员不能直接修改eip) 对应c语言中的函数调用
movl $0x12345, %eip (伪指令,程序员不能直接修改eip)
ret ======> popl %eip (伪指令,程序员不能直接修改eip) 对应c语言中的return语句
只能通过特殊指令间接修改eip,比如call指令,ret指令等。
1.存储程序计算机
2.函数调用堆栈
3.中断机制
1.存储程序计算机使得计算机可以保存程序并自动化的执行;
2.堆栈:函数调用过程,得以产生函数调用框架; 传递参数;保存返回地址;提供局部变量空间等等。
堆栈相关寄存器:
esp 堆栈指针;栈顶指针
ebp 基址指针;
堆栈操作:
push : 栈顶地址减少4字节(32位)
pop: 栈顶地址增加4个字节(32位)
ebp在c语言中用作记录当前函数调用基址;
call XXXX
将eip中下一条指令的地址保存在当前堆栈栈顶;
设置cs:eip跳转代码;
XXXX:
//建立被调用函数堆栈
pushl %ebp
movl %esp, %ebp
.........函数体..........
//拆除函数堆栈
movl %ebp,%esp
popl %ebp
ret //回复刚才保存栈顶的地址给eip
中断上下文切换和进程上下文切换需要区分;
二.Linux内核源码目录结构
arch:支持很多CPU体系结构;x86目录
Documentation:文档
fs:文件系统
init:内核启动相关代码 ; main.c; 内核初始化函数;
ipc:进程间通信
kernel:内核核心代码
mm:内存管理
net:网络
include:内核大部分头文件; inlcude/asm/xxxx.h 与体系结构相关的头文件; include/linux/xxxx.h与平台无关的头文件;
lib:库
scripts:配置内核脚本;