- 通用寄存器(P36)
1)数据寄存器
AX:字乘,字除,累加器,字I/O,通用;
AL:字节乘,字节除,字节I/O,查表转换;
AH:字节乘,字节除;
BX:基址寄存器,通用,且计算存储器地址时作基址使用;
CX:计数器,通用,循环指令,字符串操作指令;
DX:数据寄存器,字乘,字除,间接I/O,通用,且放32位数的高16位,或放外设端口地址;
(16位寄存器可拆成两个8位相对独立的寄存器使用,程序中可存放操作数也可存放操作结果)
- 指针及变址寄存器
指针寄存器:
SP:堆栈指针寄存器——栈顶的偏移地址;
BP:基址指针寄存器——默认为SS段地址;
变址寄存器
SI:源变址寄存器,储存源操作数的地址;
DI:目的变址寄存器,储存目的操作数的地址;
(可存放操作数,但是只能够作16位使用)
3)、段寄存器
CS(Code Segment):代码段寄存器——对应段存放指令代码;
DS(Code Segment):数据段寄存器——对应段存放数据或变量;
SS(Stack Segment):堆栈段寄存器——对应段存放栈操作的数据;
ES(Extra Segment):附加段寄存器——对应段存放数据或变量;
4)控制寄存器
IP(Instruction Pointer):
指令寄存器——与CS联用,确定下一条指令物理地址;
计算机通过CS:IP寄存器控制指令序列的执行流程;
IP是一个专用寄存器,不可直接访问;
5)标志寄存器
FR(Flag Register):十六位
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
CF PF AF ZF SF TF IF DF OF
0:是;1:否;
状态标志(受运算结果影响)
CF(进位标志):记录运算时从最高位产生的进/借位;
PF(奇偶标志):记录运算结果二进制数低八位中‘1’的个数是否为偶数;
AF(辅助进位标志):记录运算中低四位是否进/借位;
ZF(零标志):记录运算结果是否为0;
SF(符号标志):记录运算结果是否为负;
OF(溢出标志):表明补码运算结果是否溢出;
控制标志
TF(陷阱标志):TF=1,使处理器进入单步操作方式(类似于断点,用于程序调试);
IF(中断允许标志):是否允许程序响应中断;
DF(方向标志):记录循环中存储器地址是否自减(反之自增);
6)地址的形成
存储器分段:8088/8086有20根地址线,寻址多达2的20次方字节(1MB);每段最多64KB,最少16B。
8086/8088使用20位物理地址,使用段地址:偏移地址来表达物理地址。
段地址(H)<<1 + 偏移地址(H) = 物理地址
存储器存取方式 | 段隐含 | 段替换 | 偏移地址 |
取指令 | CS | 不可 | IP |
堆栈操作 | SS | 不可 | SP |
字符串操作(源地址) | DS | ES、SS、DS | SI |
字符串操作(目的地址) | ES | 不可 | DI |
二、寻址方式
1.立即数寻址
只可用于源操作数;
若是字符常数,应加上引号,即“字符常数”;
或者是等价于常数的变量;
例:MOV BL ,20H
MOV AX,”AB”
- 寄存器寻址
物理地址 = 段基址 (由BX/BP/SI/DI给出) + 16位数;
例:MOV AX,[FFFFH]
3.直接寻址
偏移量 = 操作数给出的有效地址(默认DS,可用段超越前缀改变);
例1:DS : [2000H];
例2:VAR DW FFFF
MOV AX,VAR;(等价于MOV BX,DS:[FFFFH])
4.寄存器间接寻址
BX/SI/DI ,默认DS;
BP,默认SS;
可使用段超越前缀改变;
例:MOV AX,DS:[BX](等价于MOV AX,[BX])
5.相对寻址
物理地址 = 寄存器间接寻址 + 有符号8/16位数
例:MOV AX,16H [BX]
6.基址变址寻址
物理地址 = 基址寄存器 + 变址寄存器
例:MOV AX ,[ BX / BP] [ SI / DI ] (BP默认SS,可使用段超越改变默认)
7.相对基址变址寻址
物理地址 = 基址变址寻址 + 有符号8/16位数
例:MOV AX,-06H[BX][DI] ( [BX + DI + -06H] / -06H[BX + DI])
三、简单指令
1.数据传送
1)MOV(传送)
MOV reg/mem , imm
MOV reg/mem/seg , reg
MOV reg/seg , mem
MOV reg/mem , seg
(注:MOV的目的操作数与源操作数类型必须一致,可通过WORD PTR/BYTE PTR指定类型;段寄存器之间以及存储单元之间不能使用MOV)
(imm传给mem时立即数可以被理解为字,所以必须指明(PTR)类型)
2)XCHG(交换)
XCHG reg , reg/mem(至少有一个在通用寄存reg中)
同MOV,与mem操作时需指明类型
3)XLAT(换码指令)
XLAT ;AL<-[BX+AL]
功能等价于:MOV AH,0
ADD BX,AX
MOV AL,[BX]
- IN (输入指令)
短格式:
IN AL / AX , PORT(无符号数0~0FFH)
长格式:
IN AL / AX , DX(0~FFFFH)
- OUT(输出指令)
短格式:
OUT PORT , AL / AX
长格式:
OUT DX , AL / AX
- 堆栈操作
PUSH r16/m16/seg 操作数进栈,SP-2
(SP-1先存入高字节,SP-1再存入低字节)
POP r16/m16/seg (除CS以外)栈顶至目的操作数,SP+2
3.标志操作
LAHF/SAHL; 标志位第八位放AH/AH低八位放标志位
PUSHF/POPF; 标志寄存器进/出栈
CLC/STC; CF复/置位
CMC; CF位求反
CLD/STD; DF复/置位
CLI/STI; IF复/置位
4.地址传送
LEA r16 , mem; r16←[mem]
LDS r16 , mem; r16←[mem],DS←[mem+2]
LES r16 , mem; r16←[mem],ES←[mem+2]
附:MOV r16 , OFFSET mem; r16←[mem]
四、算术、逻辑运算指令
- ADD/ADC dest , src ;
SUB/SBB dest , src ;
(两者不能同为储存器操作数,适用于所有算术运算指令)
(OF、CF影响:当作无符号数,溢出CF=1;当作有符号数,溢出OF=1)
(OF=1,结果错误;CF=1,结果依然正确)
2)
MUL / IMUL reg/mem ; (操作数 * AL -> AX / 操作数*AX->DX.AX)
DIV / IDIV reg/mem ; (AX/r8 , 商->AL , 余->AH )
(DX.AX/r16 , 商->AX, 余->DX)
(unsigned/signed) (除法不影响标志位,但结果产生溢出时引发中断)
3)
INC res/mem ;
DEC res/mem ;
(不影响CF)
4)
CBW ; (B->W,AL的符号位->AH)
CWD ; (W->D, AX的符号位->DX)
若符号位=0,则AH = 00H或DX = 0000H;
若符号位=1,则AH = 0FFH或DX = 0FFFFH;
5)
AND dest ,src
NOT dest , src
OR dest , src
XOR dest , src
NOT reg/mem(*)
NEG reg/mem(**)
TEST dest , src(***)
设置OF=CF=0;其他根据结果设置
*NOT不影响标志位
**NEG实质是用0减去这个数,标志按SUB规律改变
***TEST按位逻辑与,对FLAG影响同AND
6)
SAL/SAR reg/mem , 1/CL算术移位,右移时最高位不变;
SHL/SHR reg/mem , 1/CL 逻辑移位;
(影响OF、SF、ZF、PF、CF等FR)
ROL/ROR reg/mem ,1/CL 不带CF的循环移位
RCL/RCR reg/mem , 1/CL 带CF的循环移位
(影响OF、CF等FR)
(RCL/RCR 可用来实现32位移位中对高16位的操作)
(移位位数为1时,最高位改变,OF置1;不影响SF、ZF、PF)
五、串操作
1)MOVSB / MOVSW ; ( ES : [DI] <- DS : [SI] )
2)STOSB / STOSW ; ( ES : [DI] <- AL / AX )
3)LODSB / LODSW ; ( AL / AX <- DS : [SI] )
REP + 1) / 2) / 3) ; (DF控制方向,CX控制次数)
注:1、2、3一次执行一个操作,与rep联用实现多个操作;
4)CMPSB / CMPSW ; (DS : [SI] — ES : [DI])
5)SCASB / SCASW ; ( AL - ES:[DI])
REPE / REPZ + 4) / 5) ; (ZF/CF = 0, 停止执行)
REPNE / REPNZ + 4) / 5) ; (ZF=1/CF=0,停止执行)
六、中断指令
1) INTO ; (OF=0,产生4号中断)
2) IRET ; (中断返回)
3) INT n ; (中断调用)
常用中断指令:
1、01H—— (单个键入字符-->AL)
MOV AH, 1
INT 21H
2、02H—— (输出单个字符,入口地址DL)
MOV DL , 待显示字符的ASCII码
MOV AH , 2 ;
INT 21H
3、09H—— (显示以'$'结尾字符串,入口DS:DX)
LEA DX,待显示字符串首偏移地址
MOV AH ,9
INT 21H
4、10H——(输入字符串到自定义的缓冲区)
LEA DX , 缓冲区首地址
MOV AH , 10 ;
INT 21H
注:定义缓冲区
DATA DB 64 ; 定义缓冲区的字节数
DB ? ;系统填写实际输入字符总数
DB 20 DUP( $ ) ;开始存放键入的字符串
注:中断指令常与LEA、OFFSET指令联用,用于设置中断操作的入口地址;
七、子程序调用和返回
1)CALL + (far ptr ) label
压入IP(段内调用);
压入CS、IP(段间调用);
2)RET (+ num)
弹出IP(段内)(SP + 2(+num));
弹出CS、IP(段间)(SP + 4(+num));
注:与CALL联用,调用已经定义的子程序,返回为段内还是段间由CALL决定;
八、转移指令
1、无条件转移
JMP 【SHORT | NEAR PTR】 label 段内直接转移
JMP 存储单元地址 段内间接转移
(段内改变IP)
JMP FAR PTR label 段间直接转移
JMP DWORD PTR 存储单元地址 段间间接转移
2、条件转移
1)判断标志位
JZ/JNZ
JS/JNS
JO/JNO
JP/JNP
JCXZ
2)判断数大小
无符号数:(A大,B小,E等,N不)
JA / JNBE ; (大于,不小于等于)
JNA / JBE ; (不大于,小于等于)
JB / JNAE ; (小于,不'大于等于)
JNB / JAE ; (不小于,大于等于)
有符号数:(G大,L小,E等,N不)
JG / JNLE ; (大于,不小于等于)
JNG / JLE ; (不大于,小于等于)
JL / JNGE ; (小于,不'大于等于)
JNL / JGE ; (不小于,大于等于)
(注:比较的值是CMP的两个操作数)
九、循环指令
1)LOOP label ; CX!=0,转移;
2)LOOPZ label ; CX != 0 && ZF = 1,转移;
3)LOOPNZ label ; CX != 0 && ZF = 0,转移;
4)JCXZ label ; CX=0,转移;
(循环指令不影响标志位)
(内层循环应完全包含在外层内)
十、伪指令
1)ASSUNME+段寄存器:段名
2)SEGMENT+段名
段名+ENDS(成对出现)
3)ENDS(程序结束)
4)宏指令:
MICRO NAME 形参
……
代码
……
ENDM
调用:NAME 实参
(宏会在调用时自动展开,编译时代码长度和原来一样)
十一、代码格式
完整定义:
STACK SEGMENT STACK ; 定义堆栈段(可省略,系统有自带堆栈)
DB 1024 DUP(?) ; 定义堆栈段大小
STACK ENDS ; 结束堆栈段定义
DATA SEGMENT ; 定义数据段
......
数据
……
DATA ENDS ; 结束
CODE SEGMENT ; 定义代码段
ASSUME CS:CODE , DS:DATA , SS:SATCK ; 确定逻辑段类型
START: ; 程序开始
......
代码
……
CODE ENDS ; 结束
END START ; 汇编结束,程序开始点为START
简化段定义:
.MODEL small ; 程序储存模式为small
.STACK 1024 ; 定义堆栈段1024长度
.DATA ; 数据段
……
数据
……
.CODE ; 代码段
START : ; 程序开始
MOV AX,@DATA ; 设置DS指向用户定义的数据段
MOV DS,AX
……
代码
……
END START ; 汇编结束,程序开始点为START
(.model+模式;决定了转移、子程序调用、数据访问时的缺省属性;且此伪指令自动产生相应ASSUME语句)
十二、语法规范
1.标识符命名:最长31字符、第一不能是数字、'?' , '_' , '$' , '@'可放在任意位置,
但'?' , '$'不可单独使用;
2.语 句 格 式:[语句标号: ] 指令名 操作数 ( ; 注释)
3.变 量 定 义:变量名 伪指令 初值表 ;
4.语句:
1)符号定义语句
EQU ( PURGE) 等值/解除
= 无需解除,直接重新赋值即可
- 数据定义语句
DB、DW、DD、DQ、DT
?(保留存储单元而不进行初始化)
DUP(number)重复次数
字符串必须用 “ ” 或 ‘ ’,多于2个字符只能用DB定义
5.段 定 义:段名 SEGMENT [定位] [组合] [段字] ['类别']
[定位]:PAGE(XXX00H开始,即256的倍数) PARA(XXXX0H,即16的倍数) DWORD(四倍数地址) WORD(偶数地址) BYTE(任意地址)
(默认定位PARA)
[组合]:NONE(逻辑上分离)
PUBLIC(同名均有PUBLIC连接形成一个新的逻辑段)
COMMON(同名均有COMMON长段覆盖短段)
STACK(基址->SS,初始化SP)
AT(定位在指出的边界上)
MEMORY(所有段的最高地址)
(PUBLIC、STACK链接同名段)
[段字]:USE16 / USE 32(16 / 32位指令)
(缺省16位)
['类别']:在单引号内任意名称,连接程序组织段时,同类分配相邻地址,保持代码、数据、堆栈的连续性;
6.ASSUME:ASSUME 段寄存器名:段名,……(设置段寄存器和段名的关系)
ASSUME 段名:NOTHING ; (删除对……的设置)
另:1)DS与ES的装入
MOV AX , 段名
MOV DS/ES , AX
2)SS与SP的装入(系统自动初始化)
3)CS和IP的装入
END 起始地址标号
7.定义伪指令:
1)ORG :后面的数据/指令从指定偏移地址开始('$':当前的偏移值);
2)EVEN:使下面的数据/指令从下一个偶地址开始;
3)AGAIN:使下面的数据/指令从指定n的整倍数地址开始;
8.标号label:
名称 : 语句 (短距离)
名称 LABEL 类型 : 语句(类型决定距离、(变量类型))
注:JMP 标号;时,跳不同类型,代码一样,执行操作不同;
9.过程定义:
过程名 PROC [NEAR/FAR] ; (缺省NEAR)
……
过程代码
……
过程名 ENDP
10.宏定义:
宏名 MACRO 形参表
……
宏定义体
……
宏名称 ENDM
调用:宏名称 实参表(缺省参数由空格替代)
11.属性返回运算符:
1)类型返回运算符TYPE:
类型 运算结果
BYTE 1
WORD 2
DWORD 4
QWORD 8
TBYTE 10
NEAR -1
FAR -2
- 单元数返回运算符LENGTH:
若第一个参数的形式“n DUP (数值表达式)”,则运算结果为n;否则为1
- 总字节数返回运算符SIZE:等于TYRE和LENGTH的乘积
- 段基址返回运算符SEG:返回变量或标号所在的段地址;
- 偏移量返回运算符OFFSET:返回变量或标号的段内偏移地址
例如:MOV AX , SEG DATA1
MOV AX , OFFSET DATA1
附录:
- 4.4.4类型设定运算符THIS、PTR、SHORT (P88)
分离运算符HIGH / LOW 分离高低字节
4.6.宏指令(P98)
Local伪指令、%运算符、字符操作符!、文本操作符<>
4.7重复汇编与条件汇编(P104)
REPT / ENDM伪指令 IRP / ENDM伪指令 IRPC / EN伪指令
IF XXX
4.8常用Debug命令(P108)
- 循环计数P145
辗转相除—>最大公约数P155
递归调用P161
冒泡排序and累加器 P165
DOS和BIOS功能调用P179-203
5、
课本附录 A 80x86指令表
B 伪指令简表
C Debug 命令表
D ASCII码表
E BIOS系统功能调用(INT 21H)
F BIOS 中断