第二章 寄存器
1字节是 1 Byte == 8 bit, 1字是 2 Byte == 16 bit
寄存器AX的高8位构成了AH寄存器,低8位构成了AL寄存器。AH和AL是可以独立使用的8位寄存器。
单独对AH,AL进行运算时进行的是八位运算,如果有超出的位那么最高位会被舍弃,这个舍弃并不是CPU将其完全抛弃掉,之后会有提到这个进位问题
很重要的一点是,这个进位不会影响AH或AL,有人会觉得AL超出8位之后进位会“溢出”到AH中,其实不是这样的,汇编语言在写的时候如果单独写AL或是AH,那就是两个互相独立的寄存器,互不干扰的
几条简单的汇编指令
1 | mov ax,18 将18送入寄存器AX |
非常简单的基本指令,没有难度
进行数据传送或是运算时要注意操作对象位数一致,八位对应八位,16位对应16位。
8086CPU给出物理地址的方法
地址加法器采用物理地址=段地址*16+偏移地址的方法合成物理地址。
从位数上看,这个算法没有毛病,段地址和偏移地址都是16位的,而物理地址是20位的,那么段地址*16也就是2的四次,只需进行左移四位的操作,结果就从16位变成20位了,再加上一个16位的偏移地址就合成了物理地址。
本质含义
其本质的思想是通过一个基础地址加上一个偏移地址来实现物理地址的表达。例如“用纸条记录2826这个数据”的实现,如果我们的纸条够长,可以一次记录四位数据,那么一张纸条就足以记录这个数据,但是如果我们的纸条只能一次记录三位数据,那么我们就需要制定一个约定,例如,第一张纸条记录200,第二张纸条记录826,那么我们的约定可以是:得到这两张纸条后进行这样的运算:第一张纸条的数据*10 + 第二张纸条的数据。
这就是关于物理地址给出的本质的类别。似乎是一种受限于长度而做出的无奈之举。
段的概念
内存并没有一开始就分成一个一个明确的段,而是CPU寻址时划分的,关于段并不是一个绝对的概念,一块连续的内存单元都可以看成一个段,只要确定了基础地址和段的长度即可。
基础地址也就是段地址16,也称为起始地址。偏移地址为16位,16位地址的寻址能力为 2 ^ 16 B = 64 KB,所以一个段的最大长度是64KB。
给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为 0010H 到 1000FH
0001H16 = 0010H, 偏移地址16位,变化范围为0~FFFFH,所以最大值就只需要加上FFFFH即可也就是1000FH
段寄存器
8086CPU有4个段寄存器:CS、DS、SS、ES
CS 和 IP
CS:代码段寄存器 IP:指令指针寄存器
人话就是,CS段放的是段地址,IP放的是偏移地址
设CS中的数据为M,IP中的数据为N,8086将从M16+N单元开始,读取一条指令并执行。
也可以这样表述:*8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行
读取一条指令后IP中的值自动增加,增加的值为当前指令的长度。
修改CS IP的指令
同时修改:jmp 段地址:偏移地址
例如:jmp 2AE3:3
执行后:CS=2AE3H ,IP=0003Hjmp 3:0B16
执行后:CS=0003H , IP=0B16H
还可以单独修改IPjmp ax
执行前:ax=1000H,CS=2000H,IP=0003H
执行后:ax=1000H,CS=2000H,IP=1000H
这个指令好似 mov IP,ax
8086CPU的工作流程
(1)从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器
(2)IP指向下一条指令
(3)执行指令(转到步骤1,重复这个流程)