微处理器的内部结构
微处理器的基本结构
8位微处理器的内部结构一般由算术逻辑单元、寄存器组和指令处理单元等组成。
- 算术逻辑单元(ALU):负责CPU所能进行的运算,主要是算术运算和逻辑运算。
- 寄存器组:主要用来存放临时的数据或地址,起着数据准备、数据调度和数据缓冲的作用。可编程寄存器可以分为三类:通用寄存器,地址寄存器,标志寄存器。
-
指令处理单元:负责对指令进行译码和处理。一般包括:
- 指令寄存器:用来暂存被译码处理的指令。
- 指令译码逻辑:负责对指令进行译码,获知该指令的功能。
- 时序和控制逻辑:按一定时序发出和接收时钟信号、控制信号、请求和相应信号等。
8088/8086的功能结构
8088内部结构
- 总线接口单元(BIU):由指令队列、指令指针、段寄存器、地址加法器和总线控制逻辑等构成。
- 执行单元(EU):由ALU、通用寄存器、地址寄存器、标志寄存器和指令译码逻辑等构成,负责指令的译码、执行和数据的运算。
- 指令预取:指令的读取在BIU单元,执行在EU单元,可并行。BIU单元的指令读取实际上就是指令预取。
注意:8088和8086两个芯片都是16位的,内部的运算器和寄存器都是16位,都具有20位地址线,唯一区别是外部数据总线,8088是8位,8086是16位。
8088/8086的寄存器结构
8088/8086的寄存器组有8个通用寄存器、4个段寄存器、1个标志寄存器和1个指令指针寄存器,均为16位。
通用寄存器
-
数据寄存器
8088有4个16位数据寄存器,分别是:
- AX累加器(Accumulator)—>AH,AL(高8位和底8位),以下类似。
- BX基址寄存器(Base)—>BH,BL
- CX计数器(Counter)—>CH,CL
- DX数据寄存器(Data)—>DH,DL
-
变址寄存器
- SI源地址寄存器(Source)
- DI目的地址寄存器(Destination)
-
指针寄存器
- BP基址指针寄存器
- SP堆栈指针寄存器
指令指针寄存器
- CS代码段寄存器:指示代码段的开始位置
- IP指令指针寄存器:指示当前指令在代码段的偏移位置。
标志寄存器
- 状态标志
- CF进位标志:运算结果的最高有效位有进位或借位时CF=1,否则CF=0。
- ZF零标志:运算结果为0时ZF=1,否则ZF=0。
- SF符号标志:运算结果最高有效位为1时SF=1,否则SF=0。
- PF奇偶标志:反映的是最低字节中1的个数的奇偶性。
- OF溢出标志:有溢出OF=1,否则为0。
- 控制标志
- IF中断允许标志:用于控制外部可屏蔽中断是否可以被处理器响应。允许中断时IF=1,禁止中断时IF=0。
8088/8086的存储器结构
-
数据的存储格式
计算机存储信息的基本单位是二进制位(bit)。字或双字在存储器中占相邻的2个或4个存储单元,低字节存入低地址,高存高,字或双字单元的地址用它的低地址来表示。如字单元的内容为:[00002H] = 1234H。
-
存储器的分段管理
- 段基地址:段地址,说明逻辑段在主存中的起始位置。
- 段内偏移地址(Offset):说明偏移量。
每个存储器单元都有一个唯一的20位物理地址。而像
段地址:偏移地址
这种形式,称为逻辑地址。逻辑地址转物理地址的方法是:将逻辑地址中的段地址左移4位二进制(对应1位16进制),加上偏移地址就得到20位物理地址。 -
段寄存器
- CS代码段:存放代码段的段地址。处理器利用CS:IP取得要执行的指令。
- DS数据段:存放数据段的段地址,称之为有效地址EA。程序中的数据默认都在DS中存放。
- ES附加段:附加的数据段。
- SS堆栈段:处理器利用SS:SP操作堆栈中的数据。
8088/8086的寻址方式
语句有相似的两种,一般由分隔符分成的4个部分组成。
- 执行性语句:用于表达处理器指令格式为:
- 标号:硬指令助记符 参数,参数,...... ;注释
- 如:
MOV dest,src ;dest<—src
- 如:
- 标号:硬指令助记符 参数,参数,...... ;注释
- 说明性语句:格式:
- 名字 伪指令助记符 参数,参数,...... ;注释
立即数寻址方式
采用立即数寻址方式的操作数就直接存放在机器代码中,紧跟在操作码之后。立即数为imm。如:MOV AX,0102H ;将0102H赋值给寄存器AX
寄存器寻址方式
寄存器寻址方式的操作数存放在CPU的内部寄存器reg中。如:MOV AX,BX ;将BX里存的值赋值给AX
存储器寻址方式
-
直接寻址方式:指令中直接包含了操作数的有效地址,跟在指令操作码之后。如:
MOV AX,[2000H]
-
寄存器间接寻址方式:操作数的有效地址放在基址寄存器BX或变址寄存器SI、DI中。如:
MOV AX,[BX]
-
寄存器相对寻址方式:操作数的有效地址是寄存器内容与符号8位或16位位移量之和。如:
MOV AX,[SI+06H]
-
基址变址寻址方式:把一个基址寄存器(BP或BX)的内容加上变址寄存器(SI或DI)的内容构成有效地址EA。如:
MOV AX,[BX+SI]
-
相对基址变址寻址方式:使用基址寄存器(BX或BP)和变址寄存器(SI或DI),另外还在指令中指定一个8位或16位的位移量,这三者构成EA。如:
MOV AX,[BX+DI-06H]
数据传送类指令
通用数据传送指令
-
传送指令MOV:把一个字节或字的操作数从源地址传送至目的地址。相当于赋值操作。注意:目的操作数不能为立即数;以字母开头的十六进制数应该加一个前导0,以便与标识符区别。
- 寄存器有明确的字节或字类型,对应的立即数或存储器操作数只能是字节或字;但将立即数传送给存储器单元时,指令中给出的立即数可以理解为字,也可以理解为字节,此时必须显式指明。汇编语言用
byte ptr
表示字节类型,用word ptr
表示字类型。
- 寄存器有明确的字节或字类型,对应的立即数或存储器操作数只能是字节或字;但将立即数传送给存储器单元时,指令中给出的立即数可以理解为字,也可以理解为字节,此时必须显式指明。汇编语言用
-
交换指令XCHG:用来将源操作数和目的操作数内容互换,格式为:
XCHG reg,reg/mem
。注意:XCHG AL,byte ptr wvar+1
这条指令的理解是——将字节变量wvar指向的地址的上一个地址(即wvar+1地址)里的内容取出来与AL做交换。 - 换码指令XLAT:用于将BX制定的缓冲区中的AL指定的位移处的数据取出赋给AL。
堆栈操作指令
- 进栈指令PUSH:先使堆栈指针SP减2,然后把一个字操作数存入堆栈顶部。
- 出栈指令POP:把栈顶的一个字传送至指定的目的操作数,然后堆栈指针SP加2。注意:进栈先减地址后存内容,出栈先赋内容再加地址。把栈看做一个倒扣的箱子。
标志操作指令
- 标志操作指令:CLC、STC、CMC、CLD等。
地址传送指令
- 地址传送指令LEA:将存储器操作数的有效地址(段内偏移地址)传送至16位通用寄存器中。
算术运算类指令
加减法指令
- 加法指令ADD:使目的操作数加上源操作数,结果送到目的操作数。注意:目的操作数不能为立即数,且两个操作数不能同为存储器寻址方式。
- 加法指令ADC:结果会再加上进位标志CF送到目的操作数。
- 减法指令SUB:目的操作数减去源操作数,结果送到目的操作数。
- 减法指令SBB:结果会减去借位标志CF送到目的操作数。
- 比较指令CMP:用目的操作数减去源操作数,通过影响状态标志CF看是否有借位来判断出两个数的大小关系。
-
增量和减量指令INC和DEC:INC自增1,类似于
i++
;DEC自减1,类似于i--
。
符号扩展指令
略了,不太重要,想学的可以自行百度
乘除法指令
略,考试不考,老师没讲...
十进制调整指令
略,这个就是一个规则,很简单的...
位操作类指令
逻辑运算指令
- 逻辑与指令AND:两位都是1,结果为1,否则都为0。
- 逻辑或指令OR:只要一位为1结果就为1,全0才为0。
- 逻辑异或指令XOR:两个不相同为1,相同为0。
- 逻辑非NOT:取反,1变为0。
- 测试指令TEST:做与操作,通过影响状态标志来测试条件,一般用在条件转移指令。
规律:如果想把一个数其中某一位清零,就和0相与,其余位和1与;想把某一位置1,就和1做或,其余位和0或,想把某一位取反,和1做异或,其余位和0做异或,每一位都取反的话直接NOT操作。
移位指令
- 逻辑移位指令SHL、SHR:分别对应左移一位,最低位补零,最高位进入CF和右移一位,最高位补零,最低位进入CF。
- 算术移位指令SAL、SAR:分别对应左移一位和右移一位。格式:
SAL reg/mem,1/CL
。注意:目的操作数可以是寄存器或存储单元,后一个操作数表示移位位数,当移位数大于1时,用MOV指令给CL赋值,再用CL表示移位位数。
左移同逻辑左移相同,算数右移一位,最高位不变,最低位进入CF。
注意:判断数据的奇偶性只需要看二进制数据的最后一位(因为除最后一位,其余位都是2的倍数),最后一位只要是0,为偶数,为1就是奇数。
循环移位指令
- 不带进位循环移位指令ROL、ROR,同样带着CF标志位,但是不影响SF、ZF、PF、AF标志。
- 带进位循环移位指令RCL、RCR
控制转移类指令
在8088CPU中,程序代码安排在代码段。8088CPU有相对、直接和间接三种地址寻址方式。
8088将地址转移分为了段内转移和段间转移。
- 段内转移:在当前代码段64KB范围内转移,不需要更改CS段地址,只要改变IP偏移地址。称为“近转移”,它可以在±32KB范围跳转。如果范围在-128~+127之间,称为“短转移”。
- 段间转移:从当前代码段跳转到另一个代码段,需要更改CS段地址和IP偏移地址,称为“远转移”。
无条件转移指令
- 段内相对转移JMP指令:用距离标号处的位移量加上当前偏移地址形成转移后的偏移地址;程序跳转到标号所在的位置处,开始执行指令。
条件转移指令
- 条件转移指令JCC:注意这里的CC是一个总的表示,代表转换条件的意思,JCC只支持短转移寻址方式。下表为条件转移指令中的条件CC:
助记符 | 标志位 | 中文说明 |
---|---|---|
JZ/JE | ZF=1 | 等于零/相等 |
JNZ/JNE | ZF=0 | 不等于零/不相等 |
JS | SF=1 | 符号为负 |
JNS | SF=0 | 符号为正 |
JP/JPE | PF=1 | “1”的个数为偶数 |
JNP/JPO | PF=0 | “1”的个数为奇数 |
JO | OF=1 | 溢出 |
JNO | OF=0 | 无溢出 |
JC/JB/JNAE | CF=1 | 进位/低于/不高于等于 |
JNC/JNB/JAE | CF=0 | 无进位/不低于/高于等于 |
JBE/JNA | CF=1或ZF=1 | 低于等于/不高于 |
JNBE/JA | CF=0或ZF=0 | 不低于等于/高于 |
JL/JNGE | SF≠OF | 小于/不大于等于 |
JNL/JGE | SF=OF | 不小于/大于等于 |
JLE/JNG | SF≠OF或ZF=1 | 小于等于/不大于 |
JNLE/JG | SF=OF或ZF=0 | 不小于等于/大于 |
条件指令要利用影响标志的指令执行后的标志状态形成判定条件,所以在条件转移指令之前,常有比较CMP、测试TEST、加减运算、逻辑运算等指令。
例子:寄存器AL中是字母Y(含大小写),则令AH=0,否则令AH=-1。
CMP AL,'Y' ;比较AL与大写字母Y(ASCII码值)
JE NEXT ;相等,转移
CMP AL,'y' ;不相等继续比较AL与小写y
JE NEXT ;相等,转移
MOV AH,-1 ;不相等:AH<- -1
JMP DONE ;无条件转移,跳过另一个分支
NEXT:MOV AH,0 ;相等时的处理
DONE:......
循环指令
8088CPU设计了针对CX计数器的计数循环指令。
LOOP指令:首先将计数值CX减1,然后判断计数值CX是否为0;若不为0,转移到标号处执行;若等于0,顺序执行后面的指令。
子程序指令
子程序的作用就是用来执行一段特定功能,可以类比高级语言的函数。当主程序需要执行这个功能时,用CALL指令调用该子程序,这时程序就转移到子程序的起始处执行,在子程序最后,用RET指令返回调用它的主程序,继续指令后续指令。子程序框架如下:
子程序名称 伪指令助记符
···
ret
子程序名称 endp
中断指令和系统功能调用
DOS输入输出功能调用
子功能号 | 功能 | 入口参数 | 出口参数 |
---|---|---|---|
AH=01H | 输入一个字符 | AL=输入字符的ASCII码 | |
AH=02H | 输出一个字符 | DL=欲显示字符的ASCII码 | |
AH=09H | 输出一个字符串 | DS:DX=欲显示字符串在内存中的首地址 | |
AH=0AH | 输入一个字符串 | DS:DX=输入字符串将在内存缓冲区的首地址 |
上表罗列出了四个常用的输入输出功能调用。
注意:使用0AH号调用,程序员应事先定义好缓冲区,并且注意缓冲区的格式:第1字节填入最多欲接收的字符个数(可以是1~255,包括最后的回车符),留出第2字节用于存放功能调用时实际输入的字符个数(这里不包括回车符),从第3字节开始才存放实际输入的字符串ASCII码。
网友评论