8088/8086 CPU特点
- 采用并行流水线工作方式
- 通过设置指令预取队列实现
- 对内存进行分段管理
- 分为4个段并设置地址段寄存器,实现对1MB空间的寻址
- 支持协处理器
最小模式过程
-
8088送ALE给地址锁存器,地址不会改变
-
地址线和数据线
- (AD_0-AD_7):低八位地址和低八位数据信号分时复用.传送地址时信号为单向,传送数据时为双向.
- (A_{16}-A_{19}):高4位地址信号,与状态信号分时复用
- (A_8-A_{15}):8位地址信号
-
WR 写信号
-
RD 读信号
-
IO/M 访问内存/访问接口
-
DEN 低电平有效,允许读写操作
-
DT/R 传送方向控制
-
READY 时钟周期,相当于CLK
-
第三个周期Ready是高电平,就表示工作结束,进行第四个周期,如果是低电平,就要插入一个等待周期
-
中断请求响应
- INTR 可屏蔽中断请求输入端
- NMI 非屏蔽中断请求输入端
INTA 中断响应输出端
-
总线保持信号
- HOLD 总线保持请求信号输入端,CPU以外的其他设备要求占用总线时,向CPU发出请求
- HLDA,CPU对HOLD的响应信号
-
执行单元EU
- 总线接口单元BIU
- 从内存中取指令到指令预取队列
- 负责与内存或者IO接口的数据传送
- 在执行转移程序时,BIU使指令预取队列复位,从指定的新地址取指令,并立即传给执行单元执行.
- MN/MX 1-最大模式,0-最小模式
8088 内部寄存器
8个通用寄存器
-
数据寄存器
- AX 累加器
- BX 基址寄存器
- CX 计数寄存器(循环 串操作)
- DX 数据寄存器
-
地址指针寄存器
- SP 堆栈指针寄存器,栈顶
- BP 访问存放在内存单元的偏移地址
-
BX指向的数据段,BP指向的堆栈段
-
变址寄存器
- SI 源
- DI 目标
-
IP PC
-
FLAGS
- C 进位
- F 溢出 两个符号数,看两个进位是否相同就可以判断
- Z 为0时为1
- S 运算结果最高位为1时
- P 1的个数为偶数时为1
- A bit3向bit4有进位时为1
- T 单步工作
- IF 中断允许标志位,为1时可以相应可屏蔽中断请求
- D 串操作时确定方向
-
段寄存器(存放段基地址)
- CS 代码段 存放指令代码
- DS 数据段 存放数据
- ES 附加段 存放数据
- SS 堆栈段 暂时不用但是要保存的数据
实地址寻址
-
物理地址=段基地址*16+偏移地址
-
一个内存单元在同一时刻可以属于两个不同类型的段.
-
堆栈段
-
该看p23
-
8位寄存器中存放的均为运算的数据
-
AX CX一定是数据,BX,DX可能是地址
汇编
MOV
-
MOV指令不影响标志位
-
两操作数长度相同
-
源操作数 寄存器 存储器 立即数 目的操作数 寄存器 存储器
-
不允许同时为存储器
-
两操作数不能同时为段寄存器
-
源操作数是立即数时,目标操作数不能是段寄存器
-
IP和CS不作为目标操作数,FLAGS不作为操作数
-
不能用立即寻址给段寄存器赋值
-
MOV DX,09H(√)DX高八位是0,低八位是9
-
将 * 的ASCII码送入内存数据1000H开始的100个单元中
MOV DI,1000H
MOV CX,64H//常数100
MOV AL,2AH
AGAIN:MOV [DI],AL
INC DI
DEC CX
JNZ AGAIN//CX不为0就跳转
HLT
堆栈
- 先进先出
- push先SP--,再存数,pop先取数到AL,再SP++
- 以字为单位,一定是16位,没有8位
- 操作数可以是寄存器和存储器,但不能是立即数,但操作指令不能是立即数ddddddddddddd
底下是高地址,上面是低地址,然后先压低地址,再压高地址
交换指令
- 没有源操作数和目的操作数,一个立即数也不能有
- 不允许使用段寄存器
查表指令
- 用BX表示首地址,AL表示位移量
- BX+AL所指单元送AL
- 相当于AL是数组首地址,BX是下标,进行一次iloc访问
字符扩展指令
-
符号位扩展到高位,无符号数补0,隐含的操作数AX、DX
-
CBW 字节到字
- AL内容扩展到AX
- 最高位为1,AH=FFH
- 最高位为0,AH=00H
-
CWD 字到双字
- AX内容扩展到DX,AX
- 最高位1,DX=FFFFH
- 最高位0,DX=0000H
LEA指令
-
源操作数必须是存储器,目的操作数通常是间址寄存器
-
将变量的16位偏移地址写入到目标寄存器
-
MOV读取的内容,LEA读取的地址
-
将数据段中首地址为MEM1的50个字节的数据传送到同一逻辑段首地址为MEM2的区域存放,编写相应的程序段。
-
LEA SI,MEM1 LEA DI,MEM2 MOV CL,50 NEXT:MOV AL,[SI] MOV [DI],AL//两个存储器中间不能直接传,需要通过寄存器 INC SI INC DI JNZ NEXT HLT
LDS、LES
- 将一个32位的远地址指针写入目标寄存器
- LDS:将源操作数的偏移地址送目标寄存器
- LES:将源操作数的偏移地址送目标寄存器,将源操作数的段地址送给ES
标志传送指令
- LAHF:将FLAGS低八位装入AH
- SAHF:AH装入FLAGS的低八位
- PUSHF:stack<-Flags
- POPF Flags<-stack
- PUSHA 所有的Rc16入栈 POPA
- Rc16:AX,CX,DX,BX,SP,BP,SI,DI
I/O端口
- IO接口中用于存储数据,可以直接被CPU访问的寄存器.
IN acc,PORT 从端口地址读入数据到累加器
OUT PORT,acc 将累加器的值输出到端口中,acc只能是AL/AX
8位时,直接给出8位地址,16位时,端口地址由DX指定.
算术运算类指令
-
ADD
-
ADC 带进位加法 d<-d+s+C
-
INC,DEC将操作数视为无符号数,会影响标志位,但是不影响进位标志C
-
无符号进位标志看C,有符号看O
-
在内存的First和Secontd开始的区域中分别 存放着2F365H和 5E024 H两个数,要求求 其和,并存入Third中。
-
注意字长是32位,加完一次后需要再加2
MOV AX,First ADD AX,Second MOV Third,AX MOV AX,First+2//要考虑进位,使用ADC ADC AX,Second+2 MOV Third+2,AX
-
求内存数据段中M1为首和M2为首的两个20字节数之和,并将结果写入M2为首的区域.
//按字节
LEA SI,M1
LEA DI,M2
MOV CX,20
CLC//make CF = 0
NEXT:
MOV AL,[SI]
ADC [DI],AL// [DI]+Al+CF->[DI]
INC SI
INC DI
DEC CX
JNZ NEXT
HLT//暂停
//按字2
LEA SI,M1
LEA DI,M2
MOV CX,10
CLC//make CF = 0
NEXT:
MOV AX,[SI]
ADC [DI],AX// [DI]+Al+CF->[DI]
ADD SI,2
ADD DI,2
DEC CX
JNZ NEXT
HLT//暂停
-
SBB (OPRD1-OPRD2-CF->OPRD1)
-
NEG (0-OPRD->OPRD),执行后除非操作数为0,否则CF都是1.
80H或者8000H执行后结果不变,但是OF置1(溢出),其他情况下均置0.就是各位取反+1 -
CMP仅影响标志位
- 在减法中,小的减大的表示有借位,C=1;
- 无符号数 CF=0 AX>=BX, CF=1,AX<BX CF=0,ZF=1,AX=BX
- 有符号数 OF SF相同时,AX>=BX,否则AX<BX
- 20个数中找最大数
LEA BX,MAX
LEA SI,BUF
MOV CL,20
MOV AL,[SI]
NEXT:
INC SI
CMP AL,[SI]
JNC GOON //CF=0转移
XCHG [SI],AL
GOON:DEC CL
JNZ NEXT//如果不为0就跳转
MOV [BX],AL
HLT
乘除运算指令
乘法指令隐含了存放被乘数的AL或AX,以及存放结果的AX或AX DX.
无符号乘法的操作数不能是立即数
除法
- OPRD字节数,执行AX/OPRD
- AL=商,AH=余数
- OPRD双字节数
- DXAX/OPRD
- AX=商,DX=余数
INC,DEC的执行不会影响CF,其他算术类指令会影响状态标志位
- 乘法运算中,乘积是乘数的双倍字长
- 除法要求被除数是除数的双倍字长
逻辑运算指令
-
除了"非",其余指令的执行都会影响除AF外的标志
-
无论运算结果如何,都会使CFOF清零
-
AND AL,0FH 实现掩码
-
AND AX,AX 使得CFOF清零
-
从地址为3F8H端口读入一个字节数,如果该数bit1位为1,则可从38FH端口将DATA为首地址的1个字输出,否则不能进行数据传送
MOV DX,3F8H WATT:IN AL,DX AND Al,02H JZ WATT MOV DX,38FH MOV AX,DATA OUT DX,AX
-
OR 使得某些位为1
-
非运算对标志位无影响
-
XOR AX,AX 清零
-
TEST OPRD1,OPRD2,执行与运算,demo结果不写回
-
从地址为3F8H端口读入一个字节数,如果该数bit1位 bit3位和bit5位同时为1,则可从38FH端口将DATA为首地址的1个字输出,否则不能进行数据传送
LEA SI,DATA MOV DX,3F8H WATT:IN AL,DX AND AL,2AH XOR AL,2AH//0010 1010,如果这些位都是1,那么XOR后一定为0 JNZ WATT MOV DX,38FH MOV AX,[SI] OUT DX,AX
移位操作指令
-
当目标操作数为存储器操作数时,需要说明其字长,移动的位数只能是1或者是CL
-
算术左移逻辑左移:最高位移到CF,最低位为0
-
逻辑右移:最低位->CF,最高位0
-
算术右移:最低位->CF,最高位变符号位
-
循环移位可以戴震进位也可以不带CF
-
循环指令左右 对于某些状态进行测试
- 高位和低位的交换
- 与非循环移位组成32位或者更长字数的移位
LEA SI,MI
LEA DI,M2
MOV CH,4
NEXT:MOV AL,[SI]
MOV BL,AL
AND AL,0FH
OR AL,30H
MOV [DI],AL
INC DI
MOV AL,BL//还原
MOV CL,4
SHR AL,CL
OR AL,30H
MOV [DI],AL
INC DI
INC SI
DEC CH
JNZ NEXT
HLT
串操作指令
-
要求两个操作数都在存储器,针对数据块和存储器的操作
-
串所在的区域 串的首地址 串的长度 方向
-
源串一般在数据段,偏移地址SI指定
-
目标串必须在附加段,由DI指定
-
串的长度由CX指定
-
操作方向DF=0增地址,DF=1减地址
-
REP CX!=0时,REP后的指令将继续重复执行
-
REPE CX!=0且ZF=1,重复执行
-
REPNE CX!=0且ZF=0,重复指令
-
MOVS
-
增地址
- 串传送 指针指向串尾+1
- 串比较:指针指向结束位+1
-
减地址
- 串尾-1
- 结束位-1
-
串扫描指令 用于在指定存储区域中寻找某个关键字
-
SCAS OPRD
-
MOV DI,2000H MOV BX,DI MOV CX,0AH MOV AL,'A' CLD//将DF清零,为增方向 REPNZ SCASB JZ FOUND MOV DI,0 JMP DONE FOUND:DEC DI//注意停下的时候还在+1的位置 MOV DATA2,DI INC DI SUB DI,BX DONE: MOV DATA1,DI HLT
-
LODS OPRD
-
AL<-[DS:SI]
-
AX<-[DS:SI]
-
将某个区域的数据串依次装入累加器,以便显示或输出到接口,
-
串存储指令
STOS OPRDAL -> [ES:DI]
AX -> [ES:DI]
用于将内存中的某个区域置成相同的值 -
注意事项
- 需要定义附加段
- 需要设置数据的操作方向
- 源串和目标串的指针分别为SI和DI
- 传送类指令前加无条件重复前缀
- 串比较类指令前加条件重复前缀,但前缀不影响ZF状态