汇编语言与微机接口
8086微处理器结构
8086结构
总线接口部件BIU
- 从内存取指令到指令队列
- 取操作数并放到指定单元
- 通过20位地址加法器产生地址
执行部件EU
- 从指令队列取指令
- 译码
- 接受总线数据
- 算数运算
专用寄存器
- SP:堆栈指针寄存器
- BP:基址指针寄存器(SS:BP)
- DI:目的变址寄存器(DS:DI)
- SI:源变址寄存器(DS:SI)
通用寄存器
- AX:累加器,所有I/O指令通过AX传送信息
- BX:基址寄存器(DS:BX),XLAT放表首
- CX:计数寄存器,循环或串操作放计数值
- DX:数据寄存器。I/O寻址时放I/O端口地址。32位乘除法,放高16位数。
FLAGS
标志 | 含义 |
---|---|
OF | 溢出 |
DF | 方向标志,0增 |
IF | 中断允许(INTR受影响,NMI不受影响) |
TF | 单步中断 |
SF | 符号标志 |
ZF | 零标志 |
AF | 半进位(低4位向高4位进位、借位) |
PF | 奇校验 |
CF | 进位借位标志 |
8086CPU引脚及功能
8086编址
8088/8086有20根地址线,可寻址1MB空间,采用小端存储方式
- 物理地址:20位
- 逻辑地址:16位段基址,16位段偏移(段最大64K,段基址需为16的倍数,即低4位为0)
8086工作相关
最小模式:只有一块8086
最大模式:多个cpu,一个主cpu8086,一个协cpu8087
T状态:cpu处理动作最小的单位
8088最小模式下引脚及功能
- 8086最小引脚与8088不同为
- 8086:$AD15-AD0$
- 8088:$AD7- AD0,A8- A15$
引脚 | 功能 | 相关操作 |
---|---|---|
AD7 ~ AD0 | 地址/数据(A/D)复用总线,双向,三态 1. T1态,为地址总线 2. T2~T4态,为数据总线 |
存储器/IO |
A8 ~ A15 | 地址总线 | 存储器/IO |
A19~A16/S6-S3 | 地址/状态复用总线 | 存储器/IO |
ALE | 地址锁存信号 高电平表示A15 ~ A0地址有效 |
存储器/IO |
$\overline{DEN}$ | 数据允许信号 低电平表示总线上有有效数据 |
存储器/IO |
$IO/\overline{M}$ | 存储器/IO访问信号 | 存储器/IO |
READY | 数据(IO/M)准备就绪信号 | 存储器/IO |
$DT/\overline{R}$ | 数据传送方向信号 高电平写,低电平读 |
存储器/IO |
$\overline{RD}$ $\overline{WR}$ |
读写信号,三态输出,低电平有效 | 存储器/IO |
INTR | 可屏蔽中断请求信号 INTR=1,表示有中断请求,IF=1,响应中断 |
可屏蔽中断 |
$\overline{INTA}$ | 中断响应信号 第一个负脉冲,表示CPU响应中断申请INTR 第二个负脉冲,通知外设向数据总线放中断类型号 |
可屏蔽中断 |
NMI | 不可屏蔽中断请求信号 上升沿触发,执行完当前指令后立即响应中断,不受IF控制 |
不可屏蔽中断 |
$\overline{TEST}$ | 测试信号 执行WAIT指令时,每个时钟周期测试$\overline{TEST}$若为1,继续等待,直到为0 |
WAIT |
RESET | 复位信号至少保持4周期 标志寄存器为0,IP/DS/SS/ES为0,CS=FFFFH,指令从FFFF0H开始执行 |
|
HOLD | 总线请求信号 其它控制器请求使用总线 |
DMA |
HLDA | 总线请求响应 高电平时,CPU让出总线 |
DMA |
$MN/ \overline{MX}$ | 工作模式选择信号 高电平表示最小模式 |
|
CLK | 时钟信号 |
总线周期
- 一般需要4个时钟周期
- T1:ALE为高电平,A0~A19输出地址
- T2
- 写周期将数据送到总线上,$\overline{DEN}$为低持续到T4结束,$\overline{WR}$为低持续到T3
- 读周期A19-A16/S6-S3输出状态到T4结束
- T3
- 读周期$\overline{DEN}, \overline{RD}$为低,持续到T4,AD0 - AD7输出数据到T4
- T4
- 可以加READY信号,若为电平,则延续一个周期T3,到下个周期继续检查READY
8088读周期
8088写周期
8086指令系统
寻址方式
- 立即寻址
- 寄存器寻址
- 直接寻址 (段重设)
- 寄存器间接寻址(BX, BP, SI, DI)
- 寄存器相对寻址
- 基址变址寻址
- 基址变址相对寻址
数据传送指令
PUSH/POP source/dest
- 16位
- 不能是立即数
MOV dest, source
- 段寄存器不能与段寄存器与立即数直接传送
- 存储器间不能直接传送
- cs、ip,立即数不能做目的操作数
XCHG dest, source
- 交换指令,操作数必须有寄存器
- 不能有段寄存器
XLAT [source]
- BX首地址,AL偏移量
- AL<=[BX+AL]
1 |
|
CBW/CWD
- 隐含寻址,AX/DX
- CBW AL符号扩展至AH
- CWD AX符号扩展至DX
LEA dest, source
- 装入source的偏移地址
LDS/LES dest, source
- LDS REG, MEM
- 将MEME开始的4字节,低2字节送入REG,高2字节送入DS。
- LES
- 将MEME开始的4字节,低2字节送入REG,高2字节送入ES。
LAHF/SAHF/PUSHF/POPF
- LAHF:AH <= Flags低8位
- SAHF:AH => Flags低8位
- PUSHF:FLAGS入栈
- POPF:将当前栈顶两个单元的内容弹出到FLAGS(会改变TF)
输入输出指令
IN acc, sourcd; OUT dest, acc
- 只能与AL/AX数据传输
- 端口地址为8位时,可以直接给出端口地址
- 端口地址为16位时,必须由DX给出端口地址
算数运算指令
1 |
|
指令 | 含义 |
---|---|
DAA | AL转为压缩BCD码 |
AAA |
移位指令
移动一位:直接给出,移动更多位:必须由CL给出移动位数
当只位移一位时:
- 左移:CF与最高位相同,OF=0
- 右移:CF与最低位相同,OF=0
否则OF状态不定
指令 | 含义 | 影响标志 |
---|---|---|
SHL/SAL | 算数逻辑左移 低位补0,高位移到CF |
OF/ZF/CF/PF/SF |
SHR | 逻辑右移 高位补0,低位移到CF |
OF/CF |
SAR | 算数右移 高位补符号,低位移到CF |
不影响OF、AF影响CF/PF/SF/ZF |
ROL | 不带CF的循环左移 高位移入CF与最低位 |
CF/OF |
ROR | 不带CF的循环右移 低位移入CF与最高位 |
CF/OF |
RCL | 带CF的循环左移 高位移入CF,CF移入最低位 |
CF/OF |
RCR | 带CF的循环右移 低位移入CF,CF移入最高位 |
CF/OF |
串操作指令
串操作指令是8086指令系统中唯一能直接处理源操作数和目的操作数都在内存的指令
- 源串:DS:SI,可段重设
- 目标串: ES:DI,不可段重设
- 串长度放在CX中
- 串操作后SI/DI自动根据DF变化,DF=0,向地址增量方向修改
- 重复前缀在每次执行完串操作后自动修改CX
重复操作前缀
- REP
- REPE/REPZ:相等时重复($ZF = 0, CX \neq 0 $)
- REPNE/REPNZ:不相等时重复($ZF = 1, CX \neq 0$)
- 串传送指令
1 |
|
- 串比较指令
- 改变标志位,通常配合REPE/PEPNE使用
1 |
|
- 串扫描指令
- 将目标串(ES:DI)值与AL/AX比较,只影响标志位
- 通常与REPE/REPNE配合使用
1 |
|
- 串装入指令
- 把源串(DS:SI)装入AL或AX
- 自动修改SI
- 对标志位没有影响
1 |
|
- 串存储指令
- 把AL/AX装入目标串(ES:DI)
- 指令对标志位没有影响
1 |
|
程序控制指令
跳转指令
- 段内跳转,8/16位地址
1 |
|
- 段间跳转,32位地址
1 |
|
JCC只能转移8位补码范围:
FLAG/REG | 相关跳转指令 |
---|---|
ZF | JZ/JNZ/JE/JNE |
CF | JC/JNC |
SF | JS/JNS |
OF | JO/JNO |
PF | JP/JNP/JPE/JPO |
CX | JCXZ (CX=0,转移) |
- JA/JAE/JB/JBE
1 |
|
- JG/JGE/JL/JLE
1 |
|
循环指令
- 循环次数由CX指定,$CX \neq 0 $时,循环
- LOOP
- $CX = CX - 1;$
- $ CX \neq 0 \rightarrow LOOP$
- LOOPZ / LOOPE
- $CX = CX - 1; $
- $(CX \neq 0 \& ZF = 1) \rightarrow LOOPZ $
- LOOPNZ / LOOPNE
过程调用
1 |
|
中断指令
- INT n,n为中断类型
- INT执行时将IF、TF复位
- IRET:中断返回
FLAGS设置
指令 | 操作 |
---|---|
STC (set C) | CF=1 |
CLC (clear C) | CF=0 |
STD | DF = 1 |
CLD | DF = 0 |
STI | IF = 1(允许可屏蔽中断) |
CLI | IF = 0(禁止可屏蔽中断) |
其它
指令 | 操作 |
---|---|
HLT | 停止 |
NOP | 空操作 |
汇编语言程序
伪指令
变量
- 类型:BYTE/WORD/DWORD/QWORD/TBYTE
变量的使用
- 指令中表示取该数值
- 寄存器相对寻址,或基址变址相对寻址时,表示数组
- 出现在伪指令中,一定表示偏移
表达式
- 算数运算符
1 |
|
- 逻辑运算符
1 |
|
- 关系运算符
- EQ\ NE\ LT\ GT\ LE\ GE
1 |
|
- 取值运算符
1 |
|
数据定义
- 操作数定义
1 |
|
- 重复操作符
1 |
|
段定义
1 |
|
- 定位类型:
- PARA(Paragraph)
- BYTE
- WORD
- PAGE
- 组合类型
- NONE:逻辑段不组合(默认)
- PUBLIC:不同程序模块PUBLIC中有相同名字的逻辑段被组合成一个逻辑段
- STACK:不同程序模块中用STACK声明的相同名字的堆栈段组合成一个大的堆栈段
- COMMON:不同程序模块用COMMON声明的同名逻辑段公用一块地址,段长为最长逻辑段长度,重叠部分内容为最后一个逻辑段内容
- MEMORY:逻辑段连接时,本段定位在地址最高的地方
- AT:设置段逻辑地址
- 类别
- 用单引号括起来的字符串,逻辑段连接时,将具有相同类别的段装入连续的内存区域
设定段寄存器
1 |
|
过程定义
1 |
|
宏定义
1 |
|
模块定义
- NAME 定义模块名
- TITLE 定义标题名/模块名(在没有NAME的情况下)
- 无NAME, TITLE,以文件名为程序模块名
- END [标号]: 标号为程序执行开始地址
BIOS/DOS
AH <= 功能号,在寄存器填入入口参数,INT n,分析出口参数
BIOS 键盘输入(16H)
1 |
|
BIOS 显示输出(10H)
DOS 功能调用(21H)
8086 I/O及中断
I/O
I/O的特点
- 复杂性
- 异步性:外设通常与CPU之间是异步进行操作的
- 实时性:实时系统要求输入输出能在时效内服务
- 与设备无关性:操作系统屏蔽了设备的差异
I/O的功能
- 数据的缓冲及缓存
- 信号转换
- 对外设进行管理
- 中断处理
I/O编址
- 统一编址(占用了内存的编址)
- 内存外设信号共用,不需专门的I/O指令
- 独立编址
- 地址线信号由$IO/ \overline{M}$决定
三态门输入接口 74LS244
锁存器输出接口 74LS273
带输出允许端的输出接口 74LS374/74LS373
- 带锁存OE的D触发输出接口
- 74LS374:上升沿触发
- 74LS373:高电平锁存
74LS138
$\overline{G_2A}, \overline{G_2B}, G $
$ A, B, C$
$ \overline{Y_0} - \overline{Y_7}$
基本输入输出
无条件传送
要求外设总是处于准备好状态
- 简单
- 只能用于简单外设
查询工作方式
满足条件才传送
每满足一次条件只能进行一次数据传输
- 简单
- 效率低,实时性差,速度慢
中断控制方式
外设需要时向CPU提出请求中断
- 效率高、实时性好、速度快
- 需要写相应中断程序
直接存储器存取方式(DMA)
外设不经cpu直接与存储器发生数据交换
DMA工作方式
- 周期窃取:每个DMA周期只传送一个单位数据便释放总线
- 数据块传送:DMA获得总线后,传送完一个数据块才释放总线
中断
执行程序时,发生随机事件,cpu中断正在执行的程序,转去处理事件;处理完后转回中断程序继续执行。这一过程称为中断。
中断源(8088/8086系统有256个中断源)
- 内部中断
- 异常中断:异常事件引起
- 软件中断:中断指令引起
- 外部中断
- 可屏蔽中断:INTR中断
- 非屏蔽中断:NMI中断,不受IF限制
- 外部中断响应过程
中断向量表
- 存放中断服务程序入口,每个入口占4字节,低字为中断程序段内偏移,高字为段基址
- 表从0000H开始,共1k,可存256个中断程序
1
2
3
4
5
6;将中断类型为8H的中断程序 INT0 放入中断向量表
MOV AX, 0000H
MOV DS, AX
MOV SI, 8H * 4 ;中断类型x4
MOV [SI], OFFSET INT0 ;将中断程序偏移填入中断向量表
MOV [SI+2], SEG INT0 ;将中断程序段基址填入中断向量表
数字接口
8259A
引脚
引脚 | 功能 | 功能 |
---|---|---|
D7 - D0 | 数据总线 | 数据传送 |
IR7 - IR0 | 中断请求输入 | 中断 |
INT | 向系统发INTR信号 | 中断 |
$\overline{INTA }$ | CPU发送的中断响应 | 中断 |
$\overline{CS}$ | 片选信号 | |
$\overline{RD}, \overline{WR}$ | 读写信号 | 读写控制 |
A0 | 内部寄存器选择信号 | 读写控制 |
CAS2-CAS0 | 级联信号 | 级联 |
$\overline{SP}/\overline{EN}$ | 做输入:SP;0:从片 做输出:EN;控制总线方向 |
级联 |
寄存器
寄存器 | 功能 |
---|---|
中断请求寄存器IRR | 有中断请求,相应位置1,响应后清0 |
中断屏蔽寄存器IMR | 相应位置1,屏蔽该中断 |
优先级别寄存器PR | |
现行服务寄存器ISR | 执行中断,置1,EOI后置0 |
优先级管理
方式 | 描述 |
---|---|
完全嵌套方式(固定优先级) | IR0-IR7,优先级依次降低,只有更高优先级中断可以中断当前中断 |
特殊全嵌套 | 允许同级中断嵌套,其余与完全嵌套方式相同 |
优先级自动循环 | 中断服务后优先级自动降为最低 |
优先级特殊循环 | 通过OCW2确定初始最低优先级 |
屏蔽中断
- IMR相应位置1
- 手动设置ISR,IMR
EOI方式
方式 | 描述 |
---|---|
自动中断结束 | 在第二个$\overline{INTA}$后延,8259A将ISR置0(正在中断处理,但ISR没有相应指示) 设置ICW4 |
正常中断结束 | 用于全嵌套方式,将当前ISR中优先级最高的位复位 设置OCW2 |
特殊中断结束方式 | 用于优先级会改变的非全嵌套方式 OCW2指定清除ISR中的某一位 |
系统总线连接方式
- 缓冲方式:8259A通过总线驱动器和总线相连(多片8259A)
- 非缓冲方式:8959A直接与数据总线相连
中断触发
- 电平触发:一段高电平触发
- 边沿触发:上升沿触发
ICW
- ICW1,A0=0,控制初始化
D7 | D6 | D5 | D4 | D3 | D2 | SNGL | D0 |
---|---|---|---|---|---|---|---|
16/32位系统中不起作用 | 16/32位系统中不起作用 | 16/32位系统中不起作用 | 1 | 0:边沿触发 1:电平触发 |
16/32位系统中不起作用 | 0:多片 1:单片 |
0:不需要ICW4 1;需要ICW4 |
- ICW2, A0 = 1,中断类型初始化
- 填入IR0的中断类型号需是8的倍数(低三位为0)
- ICW3,主从芯片设置
- ICW4,A0 = 1,方式控制设置
D7 | D6 | D5 | SFNM | BUF | M/S | AEOI | $\mu PM$ |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0:全嵌套方式 1:特殊全嵌套方式 |
0:非缓冲方式 1:缓冲方式 |
0:缓冲方式(从) 1:缓冲方式(主) |
0:正常结束中断 1;自动结束中断 |
0:8080/8085 1:8086/8088 |
初始化方法
- 将数据传送到AX/AL
- OUT到相应地址
OCW
- OCW1,A0 = 1, 中断屏蔽操作命令字
- 将要屏蔽的位置1
- 被保存在IMR中
- OCW2, A0 = 0, EOI/设置优先级特殊循环最低优先级
- 前三位
R | SL | EOI | D4 | D3 | L2, L1, L0 |
---|---|---|---|---|---|
0:固定优先级 1:循环优先级 |
0:L2~L0无效 1:L2~L0为最低优先级 |
1:中断结束 | 0 | 0 | 设置最低优先级别 特殊优先级中设置被复位的位 |
- OCW3
- 设置中断屏蔽方式
- 查询中断请求
- 设置P=1,对偶地址读中断请求
- 最高位为1:有中断请求,最低三位为优先级最高的中断
- 读8959A状态(IRR/ISR/IMR)
- 对偶地址读可读IRR/ISR
- 对奇地址读只读IMR
D7 | ESMM | SMM | D4 | D3 | p | RR | RIS |
---|---|---|---|---|---|---|---|
x | 0:不设置中断屏蔽方式 1:设置中断屏蔽方式 |
ESMM=1: 0:清除特殊屏蔽 1:设置特殊屏蔽 |
0 | 1 | 0:非查询方式 1:查询方式 |
1:读 | 0:读IRR 1:读ISR |
8253
软件控制/硬件控制
- 软件控制:写入计数器初值触发
- 硬件控制:GATE上升沿触发
SC1 | SC0 | RW1 | RW0 | M2 | M1 | M0 | BCD |
---|---|---|---|---|---|---|---|
0:计数OUT为低,结束OUT为高 1:计数OUT为高,结束发出一个负脉冲 |
1:重复计数 | 0:软件触发 1:硬件触发:GATE上升沿触发 |
8255
方式1
- 输入(INTE与STB公用)
信号 | 作用 |
---|---|
$\overline{STB}$ | 选通信号(外设发给8255) A:PC4; B:PC2 |
IBF | 输入缓冲满,8255输出 A:PC5; B:PC1 |
INTR | 中断信号,8255输出 A:PC3; B:PC0 |
INTE | 中断允许 A:PC4 B:PC2 |
- 输出(INTE与ACK公用)
信号 | 作用 |
---|---|
$\overline{OBF}$ | 输出缓冲满,8255输出 A:7 B:1 |
$\overline{ACK}$ | 外设发出,已取走数据 A:6 B:2 |
INTR | A:3 B:0 |
INTE | A:PC6 B:PC2 |
方式2
只有A口有,综合输入输出信号
模拟量输入输出
D/A转换技术指标
- 分辨率:二进制数每变化一位,输出电压的变化
- 转换精度:实际输出和理论值的最大偏差
- 转换时间:从开始转换到与满量程差$\pm \frac{1}{2}$LSB所对应模拟量所需的时间
0832产生锯齿波
1 |
|
AD转换器分类
- 计数型(速度慢、价格低)
- 双积分型:分辨率高、抗干扰好、转换速度慢
- 逐位反馈型:转换精度高、速度快、抗干扰性差
AD转换技术指标
转换精度
量化间隔:一个LSB对应的模拟量
量化误差
- 转换时间:进行一次转换所需的时间
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!