【汇编语言与微机原理】 期末半开卷复习整理(上)

8086CPU寄存器

8086:16位,4.77MHz~10MHz,16根数据线,20根地址线
AX/AL:乘除法指令中用作累加器,IO指令中用作数据寄存器,可显式或隐含调用
AH:在LAHF用作目的寄存器,隐含调用。
AL:在BCD码用做累加器,隐含调用。
BX:在存储器寻址用作地址/基址寄存器,显式调用。在XALT用作基址寄存器,隐含调用
CX:循环计数器,隐含
CL:在移位、循环移位中用作移位次数,显式
DX:在I/O指令用作地址寄存器,显式调用。在乘除法用作辅助累加器,隐含调用
BP:堆栈段基址寄存器,显式。
SP:堆栈指针,隐含
SI:字符串操作源地址寄存器,隐含。存储器寻址用作地址寄存器,显式。
DI:字符串操作目的变址寄存器,隐含。存储器寻址用作地址寄存器,显式。
CS:代码段寄存器。
SS:堆栈段
DS:数据段
ES:附加段
IP:即将执行的指令的偏移地址,不能读/显式设定
PSW

15~12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF
overflow 指针方向 中断 单步 sign zero 辅助进位 最低位字节“1“个数 carry
IF=1,允许中断 TF=1,单步 低4位对高四位进位 为偶数时PF=1

CLI/STI:执行CLI,IF=0。执行STI,IF=1。
存储空间:按字节编址, 2 20 2^{20} 220=1MB寻址空间,00000H~FFFFFH,小端存储(低位低字节,高位高字节)。段:0000H~FFFFH(64KB),每个逻辑段最大64KB。
物理地址:物理地址=段地址:偏移地址。物理地址=段地址*16+偏移地址,各段可能重叠
:CS:IP为即将执行的指令,SS:SP为栈顶,DS:EA为数据段,ES:EA为附加段。

8086的控制与时序

引脚 M N / M X ‾ MN/\overline{MX} MN/MX为工作模式,接+5V为最小模式。最大模式可接8087/8089等协处理器。控制由总线控制器8288提供。接地为最大模式,不含协处理器。
RST:复位,高有效
Ready:就绪,输入,高有效。
AD15~AD0:地址/数据复用信号,地址三态输出,数据三态双向。
M / I O ‾ M/\overline{IO} M/IO:三态,选内存/外设。
R D ‾ \overline{RD} RD:三态,低有效,读
W R ‾ \overline{WR} WR:三态,低有效,写
ALE:输出,地址锁存允许,正脉冲下降沿锁存地址。
D T / R ‾ DT/\overline{R} DT/R:三态输出,=1时发送数据,=0时接收数据。
D E N ‾ \overline{DEN} DEN:三态低有效,表明AD15~AD0在传数据。
** B H E ‾ / S 7 \overline{BHE}/S_7 BHE/S7:三态输出,分时复用,为0时, D 15 D_{15} D15~ D 8 D_8 D8位有效
S6S5:S6=0,S5=IF
A 19 A_{19} A19~ A 16 A_{16} A16/ S 6 S_6 S6~ S 3 S_3 S3:地址状态复用
S 4 S 3 S_4S_3 S4S3:段。00ES,01SS,10CS,11DS
D 15 D_{15} D15~ D 8 D_8 D8连奇体, D 7 D_7 D7~ D 0 D_0 D0连偶体。从奇地址读一个字,需要2个总线周期。

B H E ‾ \overline{BHE} BHE A 0 A_0 A0
0 0 从偶读字, A D 15 AD_{15} AD15~ A 0 A_0 A0
0 1 从奇读字节, A D 15 AD_{15} AD15~ D 8 D_8 D8
1 0 从偶读字节, A D 7 AD_{7} AD7~ D 0 D_0 D0
1 1 高阻

总线形成:8284时钟、3个8282地址锁存,2个8286数据收发,直接提供控制。
INTR输出高有效,IF=1时相应中断请求。
I N T A ‾ \overline{INTA} INTA输出,中断响应
NMI输入,上升沿有效,不可屏蔽中断请求。
输出: A D 15 AD_{15} AD15~ A D 0 AD_0 AD0, A 19 / S 6 A_{19}/S_6 A19/S6~ A 16 / S 3 A_{16}/S_3 A16/S3时,20位地址被3片8282锁存,并锁存 B H E ‾ \overline{BHE} BHE.
8286T与 D T / R ‾ DT/\overline{R} DT/R相连, O E ‾ \overline{OE} OE D E N ‾ \overline{DEN} DEN相连,允许数据通过。
三种周期:时钟周期、总线周期、指令周期(多个总线)

总线读周期

在这里插入图片描述
执行MOV AX,[BX]
T 1 T_1 T1: M / I O ‾ M/\overline{IO} M/IO变高,对内存操作。 A 19 A_{19} A19~ A 0 A_0 A0地址信号, B H E ‾ / S 7 \overline{BHE}/S_7 BHE/S7变低)(数据高8位有效),ALE正脉冲, D T / R ‾ DT/\overline{R} DT/R变低(数据收发器接收)
T 2 T_2 T2: A 19 A_{19} A19~ A 16 A_{16} A16状态信号, A D 15 AD_{15} AD15~ A D 0 AD_0 AD0高阻, R D RD RD低(读内存), D E N ‾ \overline{DEN} DEN低(允许收发器传送)
T 3 T_3 T3: A D 15 AD_{15} AD15~ A D 0 AD_0 AD0出现数据
T 4 T_4 T4: R D ‾ \overline{RD} RD高,CPU读。 D E N ‾ \overline{DEN} DEN高,收发器与总线断开。

总线写周期

在这里插入图片描述
执行MOV[DI],BL(写8位而不是16位)
T 1 T_1 T1: D T / R ‾ DT/\overline R DT/R变高,数据收发器发, B H E ‾ / S 7 \overline{BHE}/S_7 BHE/S7高,高8位无效(与网上找的图有区别,注意具体问题具体分析)
T 2 T_2 T2: W R ‾ \overline{WR} WR低,CPU将写。 A D 15 AD_{15} AD15~ A D 8 AD_8 AD8变高阻, D E N ‾ \overline{DEN} DEN低( T 2 T_2 T2已经发数据 D 7 D_7 D7~ D 0 D_0 D0),读时 T 3 T_3 T3才有数据区别。
T 3 T_3 T3:维持不变
等待状态 T w T_w Tw:1.在 T 3 T_3 T3前沿检测Ready是否有效。2.若Ready无效,在 T 3 T_3 T3 T 4 T_4 T4之间插入 T w T_w Tw,转1。3.若Ready有效,进入 T 4 T_4 T4
T 4 T_4 T4:\overline{WR}高,CPU写
其余类似

模板与变量

调试流程:编辑(.asm),汇编(.obj),连接(.exe),执行。
调试debug模式下所有数据16进制。
伪指令:参数是常量、变量名,参数间用逗号分隔
模板:

.model small
.stack 100
.data
;//数据区
.code
start:
	mov ax,@data
	mov ds,ax
	;//逻辑代码
	mov ax,4c00h
	int 21h
end start

字符量值为ASCII码
‘0’=30H,‘A’=41H,‘Z’=5AH,‘a’=61H,‘z’=7AH
八进制后缀Q,
符号名 EQU 数值表达式在汇编前就被计算
变量:DB 字,DW 字节,DD 双字,DQ 8byte,DT 10byte
重复次数 dup (重复内容)

指令

寻址

指令格式:op dst src
立即寻址:操作数在指令中
寄存器寻址:用作dst,src,除了IP、PSW,都可以寄存器寻址。CS不能为dst
存储器寻址:dst和src不能同为存储器寻址
直接寻址:EA=8/16位位移量,例如:MOV AX,[2000H]
寄存器间接寻址:EA=BX/BP/SI/DI。例如:MOV AX,[BX]
寄存器相对寻址:EA=BX/BP/SI/DI+8/16位。例如:MOV AX,06H[SI]
基址变址寻址:EA=BX/BP+SI/DI。例如:MOV AX,[BP][SI]
相对基址变址寻址:EA=BX/BP+SI/DI+8/16位移量
使用BP时,隐含段位SS。其余隐含段为DS。允许段超越。
EA可为数值,可为变量名(符号地址)
在这里插入图片描述
(CS,IP)不为目的操作数。数据类型要一致。
例如,MOV [BX][SI],1错误,类型不明确。
XCHG OPR 1 _1 1 OPR 2 _2 2交换数值(不能同为mem,不能用seg、ip、imm)
XLATAL ← \leftarrow [(BX)+(AL)]
堆栈从较大地址分配使用,向上生长。
PUSH src:SP ← \leftarrow SP-2,((SP)+1,(SP)) ← \leftarrow src(不能同为imm),必须16位
POP dstdst ← \leftarrow ((SP)+1,(SP)),SP ← \leftarrow SP+2,CS不能为dst
LEA reg,src,reg不为seg,src必须为mem(lea传送地址,mov传送内容)
LDS:reg ← \leftarrow src,dst ← \leftarrow src+2。src:reg,mem,imm。dst:mem,reg
pushf/popf:保存/恢复主程序flag

运算

CBW:AL → \rightarrow AXCBW:AX → \rightarrow DX,AX
加减法:OP dst,src,src和dst不能同为reg/为seg
INC不影响CF。
求补:NEG opr(opr ← \leftarrow 0-opr)
乘法:无符号数为MUL src,有符号数为IMUL src,src为reg/mem。为mem时,明确类型用ptr。
在这里插入图片描述
MUL: { C F , O F = 00 高位为 0 11 否则 \begin{cases}CF,OF=00&高位为0\\11&否则\end{cases} { CF,OF=0011高位为0否则
IMUL: { C F , O F = 00 高位为低一半符号扩展 11 否则 \begin{cases}CF,OF=00&高位为低一半符号扩展\\11&否则\end{cases} { CF,OF=0011高位为低一半符号扩展否则
无符号除:DIV src。有符号除:IDIV src
在这里插入图片描述
NOT不影响flag。其余逻辑运算清零CF/OF,但SF/PF/ZF根据结果设置。
移位:OP dst,src其中src为1或CL。dst为mem且应当指明类型。左移为*2,右移为/2。带进位循环移位可实现高精度。
##在这里插入图片描述

转移

转移:直接寻址(标号)、间接寻址(reg、mem)
JMP short 8位,
JMP 标号:IP ← \leftarrow IP+label相对于当前IP偏移,CS不变
JMP NEAR PTR 标号:16位范围,不包含byte/dword,为word
JMP FAR PTR 标号:IP ← \leftarrow offset next,CS ← \leftarrow seg next
无符号数:JB/JC/JNAE低于,JNB/JAE/JNC高于等于,JBE/JNA低于等于,JNBE/JA高于
有符号数:JL/JNGE小于,JNL/JGE大于等于,JLE/JNG小于等于,JNLE/JG大于
JCXZ CX=0则转移,JE相等,JNE不相等,JP PF=1则转移(1的个数为偶数)
LOOP:只短转移
LOOP opr:CX ≠ \ne = 0
LOOPZ opr(ZF=1且CX ≠ \ne = 0)
LOOPNZ opr(ZF=0且CX ≠ \ne = 0)
LOOP相当于:

DEC CX
JNZ 标号

子程序

CALL子程序名(段内直接调用):SP ← \leftarrow SP-2,(SS:IP) ← \leftarrow IPIP ← \leftarrow 子程序
RET(IP) ← \leftarrow (SS:IP)(SP) ← \leftarrow (SP)+2
RET n(IP) ← \leftarrow (SS:IP)(SP) ← \leftarrow SP+2+n
段间调用
call 子程序名
(SP) ← \leftarrow (SP-2)
(SS:SP) ← \leftarrow (CS)
(IP) ← \leftarrow 子程序入口
(CS) ← \leftarrow 子程序段
(先压段后压偏移)
段间返回
ret
(IP) ← \leftarrow (SS:SP)
(SP) ← \leftarrow (SP)+2
(CS) ← \leftarrow (SS:SP)
(SP) ← \leftarrow (SP)+2
先取偏移后取段
ret n:在csn出栈还会(SP) ← \leftarrow (SP)+n

I/O中断

物理地址=类型码*4
中断类型码/中断向量号 0~255
每个中断向量4byte,高字CS,低字IP
int:将flag入栈,清除TF、IF。CS入栈,IP入栈,最后跳转
into:检测OF。若溢出,中断类型码为4
iret:IP出栈、CS出栈,恢复flags
控制:hlt(停止) nop(空操作) wait(等到test=0)
I/O调用:参数装入指定reg,功能号装入AH
子功能装入AL,调用,返回。
int 21H:

AH 功能 参数 返回
1 输入字符,回显 AL=字符
6 读字符,回显 DL=0FFH AL=字符,ZF=0。若无字符,AL=0,ZF=1
7 输入字符,不回显 AL=字符
A 输入字符到缓冲区 DS:DX=缓冲区首地址
2 显示字符一个(检验ctrl-break) DL=字符ASCII
9 显示字符串 DS:DS=串首地址,以$结束

0DH:回车(光标回到本行第一个字符)
0AH:换行
输出文字

lea bx,string
mov cx,7;7为长度
one:mov dl,cs:[bx]
	mov ah,2
	int 21H
	inc bx
	loop one
string db "hello"
end start

输出串

lea dx,string
mov ah,9
int 21h
string db 0DH,0AH,"hello",0DH,0AH,'$'

输入5个数

mov cx,5
mov sum,0
one:mov ah,1
	int 21h
	and al,0fh
	add sum,al
	loop one

从键盘输入至多5个数

lea dx,buffer
mov ah,0ah
int 21H
mov sum,0
mov cl,buffer+1
mov ch,0
lea bx,buffer+2
one:
	mov al,[bx]
	and al,0fh
	add sum,al
	inc bx
	loop one

程序逻辑语句

双分支结构一定要跳过另一个分支体。
大小写字母ASCII码差值20H,仅 D 5 D_5 D5位不同。
用地址表实现多分支转移。数据段:addtbl dw f1,f2,f3程序段:jmp addtbl[bx]
循环:
do-while型初始化、工作、修改、控制。
while型循环:初始化、控制、跳出、工作、修改、跳回控制。

无符号字数组以-1为结束,求平均值

lea bx,array
one:cmp word ptr[bx],-1
	je done;//数组结束
	add ax,[bx]
	adc dx,0;保留进位
	inc cx;//数组元素个数
	add bx,2
	jmp one
done:jcxz null
	div cx
	mov avg,ax
	jmp exit
null:mov avg,-1

N 2 = 1 + 3 + . . . + ( 2 N − 1 ) N^2=1+3+...+(2N-1) N2=1+3+...+(2N1)求平方根

square proc near
	push cx
	push bx
	mov bx,ax;要求的数
	mov al,0
	mov cx,1
next:sub bx,cx
	jb done
	inc al
	add cx,2
	jmp next
done:
	pop bx
	pop cx
	ret
square endp

可以自带数据区,在ret后、endp前,用cs段超越
表达式计算:
Z = 100 ( X / Y + W ) + R Z=100(X/Y+W)+R Z=100(X/Y+W)+R

mov ax,x
cwd
idiv y
add ax,w
mov bx,100
imul bx
mov cx,ax
mov bx,dx
mov ax,r
cwd
add ax,cx
adc dx,bx
mov z,ax
mov z+2,dx

中断服务程序示例

point dw 0
temp db 500 dup(?)
intproc proc far
	push ds
	push ax
	sti
	mov ax,seg temp
	mov ds,ax
	mov bx,point
	in al,60H
	mov temp[bx],al
	int pont
	cli
	mov al,20H
	out 20H,al
	pop ax
	pop ds
	iret
intproc endp

猜你喜欢

转载自blog.csdn.net/qq_46640863/article/details/123863597