一、计算机是如何工作的?
1、存储程序计算机工作模型
1)冯诺依曼体系结构
学习研究计算机的基本概念。就是指存储程序计算机。所有的有计算功能的电子设备小到计算器,大到超级计算机核心部分都可以用这种体系结构来描述。
2)存储程序计算机工作模型
从硬件(计算机的主板):逻辑上抽象为,CPU与内存之间通过总线连接,CPU内部有一个关键寄存器IP(Instruction Pointer)(在16位CPU中叫IP,在32位CPU中叫EIP,在64位CPU中叫RIP),总是指向内存的某块区域,指向内存中的代码段CS(Code Segment)。CPU从IP指向的内存地址取一条指令执行,完成后IP自+1,执行下一条指令,之后重复取指令执行。
从程序员:内存保存指令和数据,CPU负责解释和执行这些指令。
3)CPU识别什么样的指令?如何定义?
API:程序员与计算机的接口界面。
ABI:程序与CPU接口界面
- 汇编指令
- 约定使用什么样的寄存器
- 对X86来讲,多数指令可直接访问内存
EIP:在X86计算机中EIP指向内存的一条指令,EIP自动加到下一条指令,每条指令的长度不同,也可被CALL、RET、JMP、condition JMP指令修改。
2、X86汇编基础
1) X86 CPU的寄存器
1.通用寄存器:
32位的寄存器中,低16位作为16位的寄存器:AX、BX、CX、DX。
开头为E的寄存器是32位。累加器EAX、基地址寄存器EBX、计数寄存器ECX、数据寄存器EDX、堆栈基指针EBP(重要)、变址寄存器ESI和EDI、堆栈顶指针ESP(重要)。堆栈是计算机中基础性的东 西。
开头为R的寄存器是64位。机制上与32位差别不大。
2.段寄存器:
CS——代码段寄存器(Code Segment Register),其值为代码段的段值;
DS——数据段寄存器(Data Segment Register),其值为数据段的段值;
ES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
SS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值;
FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。
其中代码段和堆栈段使用最多。CPU在实际取指令时根据cs:eip来准确定位一个指令的内存地址。
3.标志寄存器:
用于标识当前状态。
2)常见汇编指令
1.mov指令及几种内存寻址方式
b,w,l,q分别代表8位,16位,32位和64位
- 寄存器寻址,以%开头的寄存器标示符,操作寄存器,与内存无关。
- 立即寻址,立即数是以$开头的数值,与内存无关。
- 直接寻址,直接访问一个指定的内存地址的数据。没有$则表示地址,将内存地址0x123指向的内存数据放入edx寄存器。
- 间接寻址,将寄存器的值作为一个内存地址来访问内存,寄存器ebx存的值作为内存地址,将内存地址存储的数据放入edx。
- 变址寻址,在间接寻址之时改变寄存器的数值。
- Linux使用的A&T汇编格式与Intel汇编略有不同。
2.几个重要汇编指令push pop call ret
- 压栈:把eax这个寄存器压栈到堆栈的栈底,ebp指向栈底,将eax放到esp所在的内存位置。栈的位置在增长。
- 出栈:栈的位置在收缩。
- 函数调用:把地址0x12345地址放到eip里,eip存储着当前cpu要读取指令的地址(指令指针),表示CPU下条指令从0x1234开始执行。
- return:ret是把之前保存的eip还原,ret后会继续执行函数调用完的下一条指令。
*表示是伪指令,不能被程序员直接使用。因为eip寄存器不能被直接修改,只能通过指令间接修改。
3)练习
例1
例2
例3
3、汇编一个简单的C程序
实验过程
实验代码
汇编代码
分析汇编代码
函数的返回值默认使用eax存储返回给上一级函数
4、总结
通过第一次学习《Linux内核分析》这门课程,我收获了许多知识。首先复习了冯诺依曼体系结构的知识,对存储程序计算机工作模型从两个方面进行了了解。之后有了解了CPU可以识别的口令。第二部分学习了X86的汇编基础知识,了解了CPU的三种寄存器,以及几种重要的寻址方式寄存器寻址,以%开头的寄存器标示符,操作寄存器,与内存无关。立即寻址,立即数是以$开头的数值,与内存无关。直接寻址,直接访问一个指定的内存地址的数据。间接寻址,将寄存器的值作为一个内存地址来访问内存,寄存器ebx存的值作为内存地址,将内存地址存储的数据放入edx。变址寻址,在间接寻址之时改变寄存器的数值。之后学习并应用了几个重要汇编指令push pop call ret,通过习题更加了解这些指令的具体含义。