汇编语言与微机接口

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指令系统

寻址方式

  1. 立即寻址
  2. 寄存器寻址
  3. 直接寻址 (段重设)
  4. 寄存器间接寻址(BX, BP, SI, DI)
  5. 寄存器相对寻址
  6. 基址变址寻址
  7. 基址变址相对寻址

数据传送指令

PUSH/POP source/dest

  • 16位
  • 不能是立即数

MOV dest, source

  • 段寄存器不能与段寄存器与立即数直接传送
  • 存储器间不能直接传送
  • cs、ip,立即数不能做目的操作数

XCHG dest, source

  • 交换指令,操作数必须有寄存器
  • 不能有段寄存器

XLAT [source]

  • BX首地址,AL偏移量
  • AL<=[BX+AL]
1
2
XLAT
XLAT source ;source为表首地址

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
;====add====
ADD A, B ;A = A + B
ADC A, B ;A = A + B + CF
INC A ;A++
;====sub====
SUB A, B
SBB A, B ;A = A - B - CF
DEC A ;A--
NEG A ;A = 0 - A
;====mul====
MUL OPRD
;AX <= AL x OPRD
;DX:AX <= AX x OPRD
DIV OPRD ;高位存余数,低位存商
;AL <= AX/ OPRD; AH <= AX % OPRD
;AX <= DX:AX / OPRD; DX = DX:AX % OPRD;
指令 含义
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. 串传送指令
1
2
3
4
5
6
7
8
9
10
11
12
13
;串传送指令
MOVS OPRD1, OPRD2 ;OPRD1为目标串地址,OPRD2为源串地址,目标串地址可段重设
MOVSB ;一次完成一字节传送
MOVSW ;一次完成一字传送

;将2000H: 1200H,开始的100个字节传送到 6000H:0000H开始的内存单元中
MOV DS, 2000H ;设置源串地址
MOV SI, 1200H
MOV ES, 6000H ;设置目标串地址
MOV DI, 0
MOV CX, 100
CLD ;DF=0,向地址增量修改
REP MOVSB
  1. 串比较指令
  • 改变标志位,通常配合REPE/PEPNE使用
1
2
3
CMPS OPRD1, OPRD2
CMPSB
CMPSW
  1. 串扫描指令
  • 将目标串(ES:DI)值与AL/AX比较,只影响标志位
  • 通常与REPE/REPNE配合使用
1
2
3
SCAS OPRD
SCASB
SCASW
  1. 串装入指令
  • 把源串(DS:SI)装入AL或AX
  • 自动修改SI
  • 对标志位没有影响
1
2
3
LODS OPRD
LODSB
LODSW
  1. 串存储指令
  • 把AL/AX装入目标串(ES:DI)
  • 指令对标志位没有影响
1
2
3
STOS OPRD
STOSB
STOSW

程序控制指令

跳转指令

  • 段内跳转,8/16位地址
1
JMP WORD PTR[BX]
  • 段间跳转,32位地址
1
JMP DWORD PTR[BX]

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
2
3
4
5
;判断CF或CF+ZF状态,判断无符号数大小
JA ;大于 CF = 0, ZF = 0
JAE ;大于等于
JB ;小于
JBE ;小于等于
  • JG/JGE/JL/JLE
1
2
3
4
JG	;大于跳转
JGE ;大于等于跳转
JL ;小于跳转
JLE ;小于等于跳转

循环指令

  • 循环次数由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
2
3
4
5
6
7
CALL NEAR PROC	;段内调用
CALL WORD PTR[SI]

CALL FAR PROC ;段间调用
CALL DWORD PTR[SI]

RET ;过程返回

中断指令

  • 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
MOV AX, NUM + (8 - 1) * 2
  1. 逻辑运算符
1
MOV AL, 0ADH AND 0CCH
  1. 关系运算符
    • EQ\ NE\ LT\ GT\ LE\ GE
1
2
MOV AX, 4 EQ 3	;MOV AX, 0000H
MOV AX, 4 GT 3 ;MOV AX, 0FFFFH
  1. 取值运算符
1
2
3
4
5
6
7
8
OFFSET	;取标号或变量的偏移地址
SEG ;取标号或变量的段地址
PTR ;类型转换

;======example======
MOV SI, OFFSET DATA1
MOV AX, SEG DATA
MOV AL, BYTE PTR[SI]

数据定义

  1. 操作数定义
1
2
3
4
5
6
7
DATA1 DB 11H, 33H
DATA2 DW ? ;未指定内容的字变量
STR DB "hello" ;定义首地址为STR的串
DATA3 DQ 0011223344556677H ;四字变量DATA3
;内存中地址由低到高存放:77H,66H,55H,44H;
;33H,22H,11H,00H
DATA4 DT 1234567890H ;定义10字节变量,高位补0
  1. 重复操作符
1
n DUP (VALUE)

段定义

1
2
3
SEGMENT_NAME SEGMENT [定位类型][组合类型]['类别']
;page: 256 Bytes
;paragraph: 16 Bytes
  • 定位类型:
    • PARA(Paragraph)
    • BYTE
    • WORD
    • PAGE
  • 组合类型
    • NONE:逻辑段不组合(默认)
    • PUBLIC:不同程序模块PUBLIC中有相同名字的逻辑段被组合成一个逻辑段
    • STACK:不同程序模块中用STACK声明的相同名字的堆栈段组合成一个大的堆栈段
    • COMMON:不同程序模块用COMMON声明的同名逻辑段公用一块地址,段长为最长逻辑段长度,重叠部分内容为最后一个逻辑段内容
    • MEMORY:逻辑段连接时,本段定位在地址最高的地方
    • AT:设置段逻辑地址
  • 类别
    • 用单引号括起来的字符串,逻辑段连接时,将具有相同类别的段装入连续的内存区域

设定段寄存器

1
ASSUME CS: CODE, DS: DATA, ES: EDATA, SS: STACK

过程定义

1
2
3
4
NAME PROC [NEAR/FAR]
;do something
RET
NAME ENDP

宏定义

1
2
3
4
5
6
7
8
9
10
11
NAME MACRO [Par1, Par2]
;do something
ENDM

MY_ADD MACRO A, B, C
XOR A, A
ADD A, B
ADD A, C
ENDM

MY_ADD AX, BX, CX

模块定义

  • NAME 定义模块名
  • TITLE 定义标题名/模块名(在没有NAME的情况下)
  • 无NAME, TITLE,以文件名为程序模块名
  • END [标号]: 标号为程序执行开始地址

BIOS/DOS

AH <= 功能号,在寄存器填入入口参数,INT n,分析出口参数

BIOS 键盘输入(16H)

1
2
3
4
5
6
7
8
MOV AH, 0	;AL <= 字符码,AH <= 扫描码,扫描码最高位为0表示按下
INT 16H

MOV AH, 1 ;ZF = 1:输入缓冲为空
INT 16H ;ZF = 0, AL <= 字符码,AH <= 扫描码

MOV AH, 2 ;判断Shift、Alt、Num是否被按下
INT 16H

BIOS 显示输出(10H)

DOS 功能调用(21H)

8086 I/O及中断

I/O

I/O的特点

  1. 复杂性
  2. 异步性:外设通常与CPU之间是异步进行操作的
  3. 实时性:实时系统要求输入输出能在时效内服务
  4. 与设备无关性:操作系统屏蔽了设备的差异

I/O的功能

  • 数据的缓冲及缓存
  • 信号转换
  • 对外设进行管理
  • 中断处理

I/O编址

  1. 统一编址(占用了内存的编址)
    • 内存外设信号共用,不需专门的I/O指令
  2. 独立编址
    • 地址线信号由$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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;正向锯齿波:从最小值增长到最大值,到最大值立刻跳变为最小值
START:MOV DX, port
NEXT0:MOV AL, 0
NEXT1:OUT DX, AL
INC AL
CMP AL, 0
JNZ NEXT1
JMP NEXT0
;反向锯齿波:从最小值跳变到最大值,然后从最大值减小到最小值
MOV DX, port
MOV AL, 0
NEXT: OUT DX, AL
DEC AL
JMP NEXT
;三角波:从最小到最大,再到最小

AD转换器分类

  • 计数型(速度慢、价格低)
  • 双积分型:分辨率高、抗干扰好、转换速度慢
  • 逐位反馈型:转换精度高、速度快、抗干扰性差

AD转换技术指标

  • 转换精度

  • 量化间隔:一个LSB对应的模拟量

  • 量化误差

  • 转换时间:进行一次转换所需的时间

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!