在csapp中增添的新理解:
1.在整个编译的过程中,编译器会完成大部分的工作,将把C语言提供的相对比较抽象的执行模型表示的程序转化成处理器执行的非常基本的指令。
2.对C程序员隐藏的处理状态:
- 程序计数器(PC,在x86-84中用%rip表示)给出将要执行的下一条指令在内存中的地址
- 整数寄存器文件包含16个命名的位置,分别存储64位的值,这些寄存器可以存储地址(即C中的指针)或整数数据,有些可用来记录某些重要的程序状态,有些用来保存临时数据
- 条件 码寄存器保存着最近执行的算术或逻辑指令的状态信息,它们用来实现控制或数据流中的条件变化
- 一组向量寄存器可以存放一个或多个整数或浮点数值
3.所有以“.”开头的行都是指导汇编器和链接器工作的伪指令。
4.数据传送指令有四个变种:movb(传送字节)、movw(传送字)、movl(传送双字)、movq(传送四字);注意,汇编代码也用“l”来表示4字节整数和8字节双精度浮点数,但这不会产生歧义,因为浮点数使用的是一组完全不一样的指令和寄存器。
5.最初的8086有8个16位的通用目的寄存器,ax、bx、cx、dx、si、di、bp、sp
6.大多数指令有一个或多个操作数——指示出执行一个操作中要使用的源数据值,以及放置结果的目的位置,有三种类型:
- 立即数:用来表示常数值,书写方式:‘$’后面跟一个用标准C表示法表示的整数
- 寄存器:表示某个寄存器的内容,用符号ra来表示任意寄存器a,用引用R[ra]来表示它的值,这是将寄存器集合看成一个数组R,用寄存器标识符作为索引
- 内存引用:它会根据计算出来的地址(通常称为有效地址)访问某个内存位置,用符号Mb[Addr]表示对存储在内存中从地址Addr开始的b个字节值的引用
总结书上的知识点:
在CPU中:
- 运算器进行信息处理;
- 寄存器进行信息存储;
- 控制器控制各种器件进行工作;
- 内部总线连接各种器件,在它们之间进行数据传送;
(外部总线则实现了CPU和主板上其他器件的联系)
对于汇编来说,CPU的主要部件是寄存器:
- 寄存器是CPU中程序员可以用指令读写的部件,可以通过改变各种寄存器中的内容来实现对CPU的控制
2.1 通用寄存器
- AX,BX,CX,DX这四个存储器通常用来存放一般性的数据,即通用存储器
- 以上四个寄存器每个又可以分为两个独立使用的8位寄存器来用:
(1)AX可分为AH和AL;
(2)BX可分为BH和BL;
(3)CX可分为CH和CL;
(4)DX可分为DH和DL。
(以AX为例,AX的低8位构成了AL寄存器,高8位构成了AH寄存器)
2.2 字在寄存器中的存储
- 字节:byte,一个字节由8个bit组成,可以存在8位寄存器中
- 字:word,一个字由两个字节组成,分为高字节和低字节
2.3 几条汇编指令
- mov ax,18:将18送入寄存器AX mov ah,78:将78送入寄存器AH add ax,8:将寄存器AX中的数值加上8
mov ax,bx:将寄存器BX中的数据送入寄存器AX中 add ax,bx:将AX和BX中的数值相加,结果存在AX中
- 在写一条汇编指令或一个寄存器的名称时不区分大小写
- 当在处理AL或AH的数据时,若相加之后有进位,进位将会丢失(PS:只是不能在8位寄存器中保存,不是真正的丢失这个进位值)
- AH和AL进行8位的运算,且AH和AL是两个不相关的寄存器;AX进行16位的计算
- 在进行数据传送或运算时,指令的两个操作对象的位数应当是一致的
2.4 物理地址
- 所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址——物理地址
2.5 16位结构的CPU
- 16位的CPU,能够一次性处理、传输、暂时存储的信息的最大长度是16位的(如地址信息)
2.6 8086CPU给出物理地址的方法
- 用两个16位的地址合成一个20位的物理地址:(乘16就是十六进制左移一位)
物理地址=段地址*16+偏移地址
(本质含义:CPU在访问内存时,用一个基础地址(段地址*16)和一个相对基础地址的偏移地址相加,给出内存单元的物理地址)
- 读写内存时:
(1)CPU中的CS(代码段寄存器)和IP(指令指针寄存器)分别提供段地址和偏移地址;
(2)段地址和偏移地址通过内部总线送入地址加法器
(3)地址加法器将两个16位地址合成为一个20位的物理地址
(4)地址加法器通过内部总线将20位物理地址送入输入输出控制电路
(5)输入输出控制电路将20位物理地址送上了地址总线
(6)20位物理地址被地址总线传送到存储器
2.8 段的概念
- 内存没有分段,段的划分来自于CPU,用一个公式给出内存单元的物理地址,使我们可以用分段的方式来管理内存
- 将若干地址连续的内存单元看作一个段,用段地址*16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元
- 段地址*16必然是16的倍数,所以一个段的起始地址一定是16的倍数
- 偏移地址位16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB
2.9 段寄存器
- 有CS、DS、SS、ES;
2.10 CS和IP
- CS:代码段寄存器 IP:指令指针寄存器
(它们的内容提供了CPU要执行指令的地址)
- 任意时刻,CPU将 CS:IP 指向的内容当作指令执行
- CPU的工作过程:
(1)从 CS:IP 指向的内存单元读取指令,读取的指令进入指令缓冲器
(2)IP=IP+所读取指令的长度,从而指向下一条指令
(3)执行指令,转到(1)重复
2.11修改 CS、IP的指令
- 转移指令:能够改变CS、IP的内容的指令
- 若想同时修改CS、IP的内容,可用
jmp 段地址:偏移地址
(功能:用指令中给出的段地址修改CS,偏移地址修改IP)
- jmp 某一合法寄存器
(功能:用寄存器中的值修改IP)
2.12 代码段
- 我们可以将长度为N(N<=64KB)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,从而定义了一个代码段
- 要让CPU执行我们放在代码段中的指令,必须要将CS:IP指向所定义的代码段中的第一条指令的首地址