第 4章 16位和 32位微处理器的指令系统及汇编语言编程教学目的和要求掌握 16位微处理器的寻址方式、指令系统及汇编语言编程,了解 32位微处理器的指令系统,并结合附录 A能够掌握汇编语言编程的上机操作教学重点
16位微处理器的寻址方式、指令系统及汇编语言编程(完整段模式)
32位汇编语言编程(简化段模式)
教学难点
微处理器的寻址方式与指令系统
汇编语言编程的基本概念和编程方法
4.1 8086微处理器的寻址方式与指令系统
4.1.1 寻址方式一条指令包含操作码和操作数两部分,操作码指出该指令要进行的操作,操作数指出该指令需要的操作数或操作数的地址。指令根据一定的方式,找到操作数或操作数的地址,然后取出操作数进行处理。寻找操作数地址的方式称为寻址方式表 4-1 8086/8088的 6种寻址方式寻址方式 汇编格式 操作数位置寄存器寻址 R 寄存器寄存器间接寻址 [R] 内存变址寻址 X[R] 内存基址变址寻址 X[BR+IR] 内存直接寻址 [EA] 内存立即寻址 n 内存代码段一、寄存器寻址汇编格式,R( R是寄存器名 )
说明:寻找的操作数在寄存器 R中例 【 4-1】 INC AX
二、寄存器间接寻址汇编格式,[R]( R是寄存器名 )
说明:寄存器 R的内容是操作数在内存的 EA,先从寄存器 R中取出操作数在内存的 EA,再根据 EA和某段寄存器生成 PA寻找操作数,所以称为间接寻址 。 能用来作间接寻址的寄存器只能是 BX,SI、
DI或 BP四者之一例 【 4-2】 MOV AX,[SI]
二、寄存器间接寻址 (续 )
表 4-2 寄存器间接寻址方式物理地址生成段 段寄存器 EA PA
数据段 DS [BX] (DS)左移 4位
+EA [SI]
[DI]
附加数据段 ES [BX] (ES)左移 4位
+EA [SI]
[DI]
堆栈段 SS [BP] (SS)左移 4位
+EA
三、变址寻址汇编格式,X[R]( R是寄存器名,X表示位移量,
其值是用 8位或 16位二进制补码表示的有符号数)。
说明:寄存器 R内容和位移量 X之和是操作数在内存的 EA。先将寄存器 R中的值和位移量 X相加求出操作数在内存的 EA,再根据 EA和某段寄存器生成 PA寻找操作数。能用来作变址寻址的寄存器只能是 BX、
SI,DI 或 BP四者之一。
例 【 4-3】 MOV BX,2[BX]
三、变址寻址 (续 )
表 4-3 变址寻址方式物理地址生成段 段寄存器 EA PA
数据段 DS [BX]+X (DS)左移 4位
+EA [SI] +X
[DI] +X
附加数据段 ES [BX] +X (ES)左移 4位
+EA [SI] +X
[DI] +X
堆栈段 SS [BP] +X (SS)左移 4位
+EA
四、基址变址寻址汇编格式,X[BR+IR]或 X[BR][IR]( BR为基址寄存器,IR为变址寄存器,X表示位移量,其值是用 8
位或 16位二进制补码表示的有符号数)
说明:基址寄存器 BR、变址寄存器 IR的内容和位移量 X三者之和是操作数在内存的 EA。先将寄存器 BR、
IR中的值和位移量 X相加求出操作数在内存的 EA,再根据 EA和某段寄存器生成 PA寻找操作数。基址寄存器只能用 BX或 BP,变址寄存器只能用 SI或 DI
四、基址变址寻址 (续 )
表 4-3基址变址寻址方式物理地址生成段 段寄存器
EA PA
数据段 DS [BX]+ [SI] +X (DS)左移
4位 +EA [BX]+ [DI] +X
附加数据段
ES [BX]+ [SI] +X (ES)左移 4
位 +EA [BX]+ [DI] +X
堆栈段 SS [BP] + [SI] +X (SS)左移 4
位 +EA [BP] + [DI] +X
五、立即寻址汇编格式,n( n是一个常数,称为立即数 )
说明:指令操作码后面单元的内容为操作数 ( 常数
n),操作数在内存代码段 。 立即寻址所提供的操作数直接放在指令中,它是紧跟在指令操作码后面的一个可用 8位或 16位二进制补码表示的有符号数 。 立即寻址主要用来给寄存器或内存单元赋初值例 【 4-6】 MOV AX,2是将立即数 2送到 AX中六、直接寻址汇编格式:含有变量的地址表达式或段寄存器,[EA]
说明:在一条指令中直接给出某一内存单元的 EA,这个 EA经过汇编后放在这条指令的下一个字单元 。
例 【 4-7】 MOV AX,[2000]是将数据段中
EA为 2000的内存单元中的内容送到 AX中 。
4.1.3 8086指令系统一、数据传送指令表 4-6数据传送指令类别 操作码 格式一般数据传送指令
MOV MOV OPD,OPS
XCHG XCHG OPD,OPS
XLAT XLAT OPS或 XLAT
4.1.3 8086指令系统一、数据传送指令 (续 1)
表 4-6数据传送指令类别 操作码 格式堆栈操作指令
PUSH PUSH OPS
POP POP OPD
4.1.3 8086指令系统一、数据传送指令 (续 2)
表 4-6数据传送指令类别 操作码 格式标志寄存器传送指令
PUSHF PUSHF
POPF POPF
LAHF LAHF
SAHF SAHF
4.1.3 8086指令系统一、数据传送指令 (续 3)
表 4-6数据传送指令类别 操作码 格式地址传送指令
LEA LEA OPD,OPS
LDS LDS OPD,OPS
LES LES OPD,OPS
输入输出指令
IN IN OPD,OPS
OUT OUT OPD,OPS
4.1.3 8086指令系统二、算术运算指令表 4-7 算术运算指令类别 操作码 格式加法指令 ADD ADD OPD,OPS
ADC ADC OPD,OPS
INC INC OPD
4.1.3 8086指令系统二、算术运算指令 (续 1)
表 4-7 算术运算指令类别 操作码 格式减法指令 SUB SUB OPD,OPS
SBB SBB OPD,OPS
DEC DEC OPD
NEG NEG OPD
CMP CMP OPD,OPS
4.1.3 8086指令系统二、算术运算指令 (续 2)
表 4-7 算术运算指令类别 操作码 格式乘法指令 MUL MUL OPS
IMUL IMUL OPS
除法指令 DIV DIV OPS
IDIV IDIV OPS
4.1.3 8086指令系统三、位操作指令表 4-8 位操作指令类别 操作码 格式逻辑运算指令
NOT NOT OPD
AND AND OPD,OPS
TEST TEST OPD,OPS
OR OR OPD,OPS
XOR XOR OPD,OPS
4.1.3 8086指令系统三、位操作指令 (续 1)
表 4-8 位操作指令类别 操作码 格式算术移位指令
SAL SAL OPD,1或 SAL OPD,CL
SAR SAR OPD,1或 SAR OPD,CL
逻辑移位指令
SHL SHL OPD,1或 SHL OPD,CL
SHR SHR OPD,1或 SHR OPD,CL
4.1.3 8086指令系统三、位操作指令 (续 2)
表 4-8 位操作指令类别 操作码格式不带进位的循环移位指令
ROL ROL OPD,1或 ROL OPD,
CL
ROR ROR OPD,1或 ROROPD,
CL
带进位的循环移位指令
RCL RCL OPD,1或 RCL OPD,
CL
RCR RCR OPD,1或 RCR OPD,
CL
4.1.3 8086指令系统四、转移指令转移指令分条件转移指令和无条件转移指令两大类,其特点是改变程序的执行顺序
(即改变指令指针 IP的值),但不改变状态标志位的状态。条件转移指令根据条件标志的状态判断是否转移。无条件转移指令则不作任何判断,无条件地转移到指令中指明的目的地址处执行。转移指令共有 19条,具体见表 4-9
4.1.3 8086指令系统四、转移指令表 4-9 转移指令类别 指令名称 操作码 转移条件简单条件转移相等 /等于 0转 JE/JZ ZF=1
不相等 /不等于 0转 JNE/JNZ ZF=0
为负转 JS SF=1
为正转 JNS SF=0
溢出转 JO OF=1
未溢出转 JNO OF=0
4.1.3 8086指令系统四、转移指令 (续 1)
表 4-9 转移指令类别 指令名称 操作码 转移条件简单条件转移进位位为 1转 JC CF=1
进位位为 0转 JNC CF=0
偶转移 JP/JPE PF=1
奇转移 JNP/JPO PF=0
4.1.3 8086指令系统四、转移指令 (续 2)
表 4-9 转移指令类别 指令名称 操作码 转移条件无符号数条件转移高于转移 JA/JNBE CF=0且 ZF=0
高于或等于转移
JAE/JNB CF=0或 ZF=1
低于转移 JB/JNAE CF=1且 ZF=0
低于或等于转移
JBE/JNA CF=1或 ZF=1
4.1.3 8086指令系统四、转移指令 (续 3)
表 4-9 转移指令类别 指令名称 操作码 转移条件带符号数条件转移大于转移 JG/JNLE SF=OF且 ZF=0
大于或等于转移
JGE/JNL SF=OF且 ZF=1
小于转移 JL/JNGE SF≠OF 且 ZF=0
小于或等于转移
JLE/JNG SF≠OF 且 ZF=1
4.1.3 8086指令系统四、转移指令 (续 4)
表 4-9 转移指令类别 操作码 转移条件无条件转移 JMP 无
4.1.3 8086指令系统五、字符串操作指令为了方便地实现字符串操作,8086/8088提供了字符串操作指令。只要按规定设置好初始条件,选用正确的字符串操作指令,就可完成规定的操作,
这些指令的前面可加重复前缀,能在条件满足的情况下反复执行,而不用考虑指针如何移动、循环次数如何控制等问题,从而简化了程序设计。字符串操作指令在使用格式和使用方法上有许多类似的地方,它们隐含使用的寄存器、标志位和符号见表 4-
10
4.1.3 8086指令系统五、字符串操作指令 (续 1)
表 4-10 字符串操作指令使用中的一些隐含约定源串指示器 DS:SI
目的串指示器 ES:DI
重复次数计数器 CX
SCAS指令的搜索值 在 AL/AX中
LODS指令的目的地址 AL/AX
4.1.3 8086指令系统五、字符串操作指令 (续 2)
表 4-10 字符串操作指令使用中的一些隐含约定
STOS指令的源地址 AL/AX
传送方向 DF=0,SI,DI自动增量 (用 CLD指令实现 )
DF=1,SI,DI自动增量 (用 STD指令实现 )
… SB 不带操作数的字节操作指令
… SW 不带操作数的字操作指令
4.1.3 8086指令系统五、字符串操作指令 (续 3)
系统规定:源串一定要在当前数据段中,
目的串只允许在当前附加数据段中。所有的串操作指令均以寄存器间接方式访问源串或目的串中的各元素,并自动修改 SI和 DI的内容。若 DF=0,则每次操作后,SI,DI自动增量(字节操作加 1、字操作加 2);若 DF=1,
则每次操作后,SI,DI自动减量(字节操作减 1、字操作减 2),使之指向下一个元素
4.1.3 8086指令系统五、字符串操作指令 (续 4)
当指令带有重复前缀时,则指令重复执行,每执行一次,
就检查一次重复条件是否成立,如成立,则继续重复;否则终止重复,执行后续指令
① REP:重复,即无条件重复 CX寄存器中指定的次数
② REPE/REPZ:相等 /为 0时重复,即 ( CX) ≠ 0( 重复次数还未为 0) 同时 ZF=1( 比较时相等 ) 时重复,否则,重复终止 。
③ REPNE/REPNZ:不相等 /不为 0时重复,即( CX) ≠ 0
(重复次数还未为 0)同时 ZF=0时重复,否则,重复终止
4.1.3 8086指令系统五、字符串操作指令 (续 5)
表 4-11字符串操作指令类别 操作码 格式字符串传送 MOVS MOVS OPD,OPS
MOVSB MOVSB
OVSW MOVSW
4.1.3 8086指令系统五、字符串操作指令 (续 6)
表 4-11字符串操作指令类别 操作码 格式字符串比较 CMPS CMPS OPD,OPS
CMPSB CMPSB
CMPSW CMPSW
4.1.3 8086指令系统五、字符串操作指令 (续 7)
表 4-11字符串操作指令类别 操作码 格式字符串搜索 SCAS SCAS OPD
SCASB SCASB
SCASW SCASW
4.1.3 8086指令系统五、字符串操作指令 (续 8)
表 4-11字符串操作指令类别 操作码 格式字符串装入 LODS LODS OPS
LODSB LODSB
LODSW LODSW
4.1.3 8086指令系统五、字符串操作指令 (续 9)
表 4-11字符串操作指令类别 操作码 格式字符串存储 STOS STOS OPD
STOSB STOSB
STOSW STOSW
4.1.3 8086指令系统五、字符串操作指令 (续 10)
表 4-11字符串操作指令类别 操作码 功能重复前缀
REP 用于字符串传送和字符串装入指令前
REPE/REPZ 用于字符串比较指令、字符串搜索指令前
REPNE/REPNZ 用于字符串比较指令、字符串搜索指令前
4.1.3 8086指令系统六,处理机控制指令表 4-12处理机控制指令 --标志位控制指令格式 功能
STC 置进位标志,1→ CF
CLC 清除进位标志,0→ CF
CMC 进位标志取反,CF求反 → CF
STD 置方向标志,1→ DF
CLD 清除方向标志,0→ DF
4.1.3 8086指令系统六,处理机控制指令 (续 1)
表 4-12处理机控制指令 --标志位控制指令 (续 1)
格式 功能
STI 置中断标志,1→ IF
CLI 清除中断标志,0→ IF
4.1.3 8086指令系统六,处理机控制指令 (续 2)
表 4-12处理机控制指令 - CPU状态控制指令格式 功能
HLT 处理器暂停
ESC OPD,
OPS
交权指令,将浮点指令交给浮点处理器执行
WAIT 等待指令,8086进入等待状态
LOCK 使 CPU在执行该指令期间封锁总线,禁止其他的总线主设备占用总线
NOP 空操作
4.2 16位汇编语言编程
4.2.1 伪指令在汇编源程序中使用一些固定格式的约定符号,这些符号主要用来告诉汇编程序如何工作,这就是汇编控制命令,也称伪指令。伪指令和机器指令(在 4.1.3中所讲的指令)最大的区别有 2点
① 伪指令是在汇编源程序汇编期间,被汇编程序识别并解释。主要是为变量申请内存空间、建立堆栈、告诉汇编程序从何处开始汇编以及到何处结束等。而可执行指令是在程序执行期间被 CPU译码并执行的
4.2.1 伪指令
② 汇编结束后伪指令就完成任务,在程序执行期间不再考虑它,因此伪指令不翻译成目标码。而可执行指令经汇编程序汇编后,变成机器可以识别并执行的目标码一,数据定义伪指令数据定义伪指令见表 4-13
格式,[变量名 ] 数据定义伪指令 表达式
[,… ]
功能:定义数据存储区,其类型由所使用的数据定义伪指令指定
4.2.1 伪指令表 4-13 数据定义伪指令伪指令 所申请的字节数
DB 1
DW 2
DD 4
DF 6
DQ 8
DT 10
4.2.1 伪指令二、符号定义伪指令
① 等价伪指令 格式,符号名 EQU 表达式功能:用来为常量,表达式及其他各种符号定义一个等价的符号名,但它并不申请分配存储单元 。
如果一个常量在程序中使用非常频繁可以用一个符号来表示它这就是符号常量。如假定学生成绩处理程序中经常使用某班的人数用等价伪指令定义为,N EQU 40。指令 MOV AX,N
在汇编时用 40代替 N变成 MOV AX,40
4.2.1 伪指令
② 等号伪指令格式:符号名 =表达式功能:该语句的功能和 EQU相似,不同的是等号伪指令能对所定义的符号名再重新定义,当使用等号语句连续定义同一符号名时,以最后一次定义的值为准
4.2.1 伪指令三,段定义伪指令格式:
段名 SEGMENT [定位方式 ][组合方式 ][ '类别 ']

段名 ENDS
功能:定义了一个以 SEGMENT伪指令开始,
以 ENDS伪指令结束,以段名命名的存储段
4.2.1 伪指令说明:
① 段名是程序员为该段所起的名字,用来指出为该段分配的存储区起始位置 。 一个程序模块可以定义为若干段,
段名可以各不相同,也可以重复,汇编程序将一个程序中的同名段处理成一个段 。 段的定义可以嵌套,但不能交叉 。 ② 定位方式,组合方式和类别是可选项,可省略 。
③ 数据段 ( 或附加数据段 ) 中一般定义常量和变量,是为程序的代码段提供数据和保存计算结果的 。 它的一般格式如下:
DATA SEGMENT
常量或变量定义
DATA ENDS
4.2.1 伪指令
④ 堆栈段为程序定义堆栈,堆栈的大小依赖于你所编写的程序对堆栈的使用程度 。 如果你省略堆栈段定义,当你的程序使用堆栈时,系统会自动建立堆栈 。 并且在汇编时会出现一个警告:,LINK:
warning L4021:no stack segment”。
对于一般的小程序可省略堆栈段定义堆栈段的一般格式如下:
STACK SEGMENT STACK
DB n DUP( 0)
STACK ENDS
其中 n是堆栈的长度,由程序员根据需要自定
4.2.1 伪指令
⑤ 代码段是程序对数据进行处理的部分 。 在一个程序中,数据段,堆栈段和附加数据段都可以省略,代码段不能省略代码段的一般格式如下:
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,
SS:STACK,ES:EDATA 假定伪指令
START:
┇ 可执行语句
MOV AH,4CH
INT 21H
CODE ENDS
END START 程序结束伪指令五、置汇编地址计数器伪指令 ORG
汇编地址计数器用符号,$”表示,它用来记录正在被汇编程序汇编的语句地址,也就是说其内容标出了汇编程序当前的工作位置 。 在一个源程序中,
往往包含了多个段,汇编程序在将该源程序汇编成目标程序时,每遇到一个新段,就为该段分配一个初值为 0的汇编地址计数器,然后,再对该段中的语句汇编 。 在汇编过程中,对凡是需要申请分配存储单元的语句和产生目标代码的语句,汇编地址计数器则按该语句目标代码的长度增值 。 因此,段内定义的所有标号和变量的偏移地址就是当前汇编地址计数器的值 。 汇编地址计数器符号,$”可出现在表达式中
4.2.1 伪指令汇编地址计数器的值可以用伪指令 ORG进行设置 。
格式,ORG 数值表达式功能:将汇编地址计数器设置成数值表达式的值 。 其中,数值表达式的值应为非负的整数,其值在 0~ 65535之间例 【 4-15】 汇编地址计数器和伪指令 ORG举例
DATA SEGMENT
ORG 4
BUF DB 'readme'
ORG $+5
NUM DB -2
DATA ENDS
4.2.2 汇编语言中的常量、变量及标号一,常量常 量 是 指 在 程 序 执 行 期 间 不 变 的 量 。 在
8086/8088宏汇编语言中可使用的常量见表 4-14。
常量主要用于伪指令中给变量赋初值,或者用作机器指令语句中的立即操作数,变址寻址和基址变址寻址中的位移量 。 常量一般可以直接以数值形式出现在汇编语句中,这种常量称数值常量 。
但对经常使用的数值常量,可以事先为它定义一个名字,然后在语句中用名字来表示该常量,这种常量称符号常量 。 伪指令 EQU和等号,=”可用来实现将数值常量定义成符号常量
4.2.2 汇编语言中的常量、变量及标号表 4-14 8086/8088宏汇编语言中所使用的常量常量分类 格式 X的取值 举例二进制常量 XX… XB 0或 1 01000001B
八进制常量 XX… XO
XX… XQ
0~ 7 1234Q
十进制常量 XX… X
XX… XD
0~ 9 123,123D
十六进制常量 XX… XH 0~ 9 A~ F 1234H,0A12FH
字符常量 'XX… X'
"XX… X"
ASCII字符 '0123'
"readme"
4.2.2 汇编语言中的常量、变量及标号二、变量在汇编语言中,变量是一个数据单元的名字,即数据存放地址的符号表示 。 它有 3个属性:
① 变量的段属性 。 指变量所在段的首地址,
当需要访问该变量时,它所在段的首地址一定要在某一段寄存器中
② 变量的偏移属性 。 指变量所在段的首地址到变量所在的存储单元之间的距离,用字节数表示 。 它表示变量在某段的相对位置,也就是我们所说的偏移地址 ( 或有效地址 ) EA
③ 变量的类型 。 指存取某变量所需要的字节数变量的定义格式如下:
[变量名 ] 数据定义伪指令 表达式 [,… ]
汇编语言中的符号常量名,变量名,段名,过程名,标号都称为标识符 。 标识符是由字母,数字 ( 0~ 9),特殊字符 (?,,,@,_,$) 等组成的字符串,但该字符串不能以数字或下划线 ‘ _’
作为开始字符 。 标识符最大长度不能超过 31个字符,并且汇编语言对字母的大写和小写没有统一要求,也就是说,汇编语言对标识符中字母的大写和小写不作区分,如 ABC,aBc,Abc和 aBC都认为是同一个标识符 。 注意不能使用汇编语言的保留字如算术运算指令名 ADD,SUB等做标识符
,① 数值表达式
② ASCII字符串 ( 只有用 DB定义变量时,才允许字符串长度超过 2个字符 )
③ 地址表达式 。 如果该地址表达式为一变量 ( 或标号 ) 名,用 DW伪指令是取它的偏移地址来初始化变量,用 DD伪指令是取它的段首址和偏移地址来初始化变量表达式的几种方式
④?(表示所定义的变量初值不确定)
⑤ 重复子句 格式,n DUP(表达式)
其中,n是重复因子,只能取正整数,它表示定义了 n个存储单元,其类型由它前面的数据定义伪指令确定。而每个存储单元中的初值由 DUP后面圆括号中的表达式给定,如果是,?,,则表示变量的初值不确定
⑥ 可以是以上表达式组成的序列,各表达式之间用逗号隔开例 【 4-16】 有下面的数据段,画出其内存分配图
DATA SEGMENT
TABLE DB 1,2,3,2 DUP(6,-2)
COUNTER EQU $-TABLE
VARY DW 1234H
CHAR DB ’123’,3 DUP(1)
POINTER1 DW VARY
POINTER2 DD CHAR
DATA ENDS
标号是机器指令语句存放地址的符号表示,也可以是过程名 。 过程名实际上是过程入口地址的符号表示,即过程第一条机器指令语句的存放地址标号的用法有两种:
① 在代码段某一指令的前面,是当前一条指令语句地址的符号表示,用来提供一个转移地址,
让其他的指令向此指令转移,一般的机器指令语句前不需要标号
② 用来表示过程入口地址三、标号
4.2.3 汇编语言中的运算符号和表达式数值表达式是利用算术,逻辑,移位或关系运算符将常量连结在一起构成的表达式,它的运算结果是一个数值
① 算术运算符共有 +,-,*,/,MOD 5个,
其中 *,/,MOD优先级相同,+,-优先级相同,
并且 *,/,MOD优先级高于 +,-。 可利用括号改变一个表达式某一部分的优先级 。 MOD是取余数,
如 7 MOD 3的值是 1
② 逻辑运算符有 AND,OR,XOR,NOT 4个,
分别是逻辑与,逻辑或,逻辑异或,逻辑非 。 逻辑运算是按位进行的,所以运算的结果仍是整数常量一、数值表达式
③ 移位运算符有左移 SHL和右移 SHR 2个运算符 。 SHL表示将常量左移运算符右边常量规定的次数,SHR表示将常量右移运算符右边常量规定的次数,所空的位补 0
④ 关系运算符有 EQ,NE,GT,LT,GE、
LE共 6个运算符,分别是等于,不等于,大于,
小于,大于或等于,小于或等于 。 关系运算的结果是两个特殊的量,若关系不成立,则结果为 0;
否则为 0FFFFH
地址表达式的值是段内偏移地址,它具有段,偏移地址及类型三个属性 。 地址表达式是由变量,常量,标号,寄存器和运算符组成的有意义的式子地址表达式除可使用数值表达式的运算符外,还可根据需要使用一些特殊运算符二、地址表达式用来指明某个变量,标号或地址表达式的类型属性,或者使它临时兼有与原定义所不同的类型属性,但保持它们原来的段属性和偏移地址属性不变 。 其格式是:
类型 PTR 地址表达式根据地址表达式的不同值,类型可以是 BYTE,WORD,DWORD,NEAR、
FAR
1.类型运算符 PTR
为了将源程序中的指令正确地翻译成目标代码,
汇编程序要求每个语句中操作数的类型要明确,如果是双操作数指令,还要求源操作数和目的操作数类型一致,既同时为字节类型或同时为字类型 。 下面分 4
种情况说明:
① 对于单操作数指令,操作数的类型必须明确
② 对于双操作数指令,只要有一个操作数类型明确就可以了
③ 如果两个操作数类型都明确,则它们的类型必须一致
④ 如果两个操作数类型都不明确,就要用 PTR来指定类型了跨段前缀,,”用于临时给变量,标号或地址表达式指定一个段属性,且只能在所出现的语句中有效,它并不改变地址表达式的偏移地址和类型属性,它的格式是:
① 段寄存器名:地址表达式,② 段名:地址表达式
MOV AX,[SI]等价于 MOV AX,DS:[SI],默认从数据段中取数据 。 若改为 MOV AX,ES:[SI],
则从附加数据段中取数据
2.跨段前缀,,”
属性分离运算符可分离出变量、
标号的段、偏移地址及类型的属性值。其格式是:分离运算符 变量或标号,运算结果是一个数值常量
3,属性分离运算符
① 段属性分离运算符 SEG。 该运算符分离出其后变量或标号所在段的首地址
② 偏移属性分离运算符 OFFSET。 该运算符分离出其后变量或标号的偏移地址
③ 类型分离运算符 TYPE
该运算符取其后变量或标号的类型 。 如果是变量,
其类型值由变量的类型确定,某一变量类型的类型值和该变量在内存中所占的字节数相同
① 取变量所含的数据存储单元个数运算符
LENGTH,格式,LENGTH 变量 。 它的取值根据定义该变量时,数据定义伪指令后面第一个表达式的形式而定,如果第一个表达式为重复子句,n
DUP( 表达式 ),,则取值为前面的重复因子 n,
如果为其他形式的表达式,则取值为 1
② 取变量所含的数据存储区大小运算符 SIZE,
格式,SIZE 变量 。 它的取值为,LENGTH变量 *
TYPE 变量,也就是说,它的取值是一个变量所占内存的实际字节数
4.其他运算符
③ 字节分离运算符 HIGH和 LOW
格式,HIGH 常量或地址表达式; LOW 常量或地址表达式其中,HIGH分离出其后常量或地址表达式的高 8位,
LOW分离出其后常量或地址表达式的低 8位 。
汇编语言中的常用的运算符的优先级见表 4-17。
4.2.4 顺序与分支程序的设计顺序型结构程序的特征是在程序的指令中无转移指令,计算机从程序的第一条指令开始顺序执行,直到程序的最后一条指令为止例 【 4-29】 在一个表中存放着 0到 9十个数字的立方值,
编程从键盘输入 0到
9之间的任意一个数,
查表找出这个数的立方值
4.2.4 顺序与分支程序的设计有分支控制的程序结构称为分支型结构 ( 或称选择结构 ) 。 分支型结构可分为二分支型结构和多分支型结构 。 在分支程序中,不同的条件往往是通过标志寄存器中条件标志的不同状态反映的 。
因此分支程序设计中一个至关重要的问题是根据各标志的不同状态选用合适的转移指令 。 转移指令分条件转移指令和无条件转移指令两大类一、条件转移语句格式,[标号,]操作符 短标号功能:如果条件满足,则 (IP)+位移量
→ IP
4.2.4 顺序与分支程序的设计在转移指令中,位移量为当前 (IP)到转移目的地址处的字节距离 。 如果当前 (IP)到某标号 (即转移的目的地址 )的位移量在 -
128~ 127之间,则该标号称为短标号 。 当位移量为正时,表示向前转;当位移量为负时,表示向后转,条件转移指令的目的地址均是短标号条件转移指令共有 18条,分成以下三类
1.简单条件转移指令共有 10条,根据单个标志的状态决定是否转移
2.无符号数条件转移指令共有 4条,根据多个标志的状态决定是否转移,这类指令将比较对象视为无符号数
3.带符号数条件转移指令共有 4条,根据多个标志的状态决定是否转移,
这类指令将比较对象视为带符号数
4.2.4 顺序与分支程序的设计二,无条件转移无条件转移指令使 CPU无条件地转移到指令中指明的目的地址处执行,在程序中用它将各分支的出口重新汇集到一起构成多分支结构,特别是当条件转移指令的转移范围超过 -128~ 127个字节时,往往要借助无条件转移指令实现
4.2.4 顺序与分支程序的设计无条件转移指令和要转移的目的地址可以在同一段,也可以在另一段 。 前者称为段内转移,后者称为段间转移 。 段内转移指令只改变指令指针 IP的内容,而段间转移指令则要同时改变指令指针 IP和代码段寄存器的内容 。 无条件转移指令可通过各种寻址方式得到要转移的目的地址,常用的有直接寻址和间接寻址两种,表 4-18列出了无条件转移指令的格式和功能说明无条件转移指令和条件转移指令有两点重要区别:一是前者的转移是无条件的,不做任何判断便转向目的单元;二是前者的转移范围不受限制,而后者只能在 -128~ 127个字节范围内转移
4.2.4 顺序与分支程序的设计例 【 4-30】 编程实现符号函数例【4 - 3 0 】程序
4.2.4 顺序与分支程序的设计对于多路分支的程序,如果直接用条件转移指令实现,
那么 N路分支,就需要 N-1条条件转移指令,程序显得冗长繁琐,可用跳转表来实现多路分支例 【 4-31】 对学生的成绩分类,分类标准见表 4-19。
下面的程序是由入口地址组成跳转表的多路分支程序例【4 - 3 1 】程序
4.2.5 循环程序设计循环型结构有 REPEAT-UNTIL模式 ( 见图 4-8)
和 WHILE模式 ( 见图 4-9) 。
4.2.5 循环程序设计
REPEAT-UNTIL和 WHILE两种模式的共同点是都有初始化部分,工作部分,调整部分和控制部分 。 这四部分的作用是:
① 初始化部分,又称循环的预置部分 。 在循环体工作之前,把工作变量 ( 保存中间结果或最后结果 ),控制变量 ( 控制循环是否结束 ),地址单元,
工作寄存器等置初值,为循环做好准备,初始化工作可保征循环程序在正确的初始状态下工作
② 工作部分,这是整个循环程序的核心部分,
它由需要重复操作的指令序列组成,工作部分随求解问题所采用的算法不同而异
③ 调整部分,为了保证工作部分每次在新的意义下工作,每执行一次工作部分,必须对操作数或操作数地址进行修改,为下一次循环作准备,同时控制变量也作相应的调整,
为控制部分的条件判定作准备。例如利用计数来控制的循环,每循环一次,计数值都要调整(增加或减少),控制部分根据计数器的值来决定是否退出循环。通常的循环结构是调整和工作部分同步工作,工作部分和调整部分合在一起,统称为循环体。
④ 控制部分:为了能在正确的时机退出循环,要有出口测试,控制部分是用来控制循环程序是继续执行还是终止。控制部分是对修改过的控制变量进行测试,
若达到预定要求,则循环结束,否则循环继续执行。控制部分根据实际情况可分为计数控制(又分为正计数和倒计数)
和条件控制两种
4.2.5 循环程序设计
REPEAT-UNTIL和 WHILE两种模式的区别是,REPEAT-UNTIL模式是先执行循环体,
再判断条件是否成立,因此对于 REPEAT-
UNTIL模式不管条件是否成立循环体至少执行一次; WHILE模式是先判断条件是否成立再执行循环体,因此对于 WHILE模式循环体可能一次也得不到执行
4.2.5 循环程序设计例 【 4-32】 已知有 N
个数据存放在以 BUF为首地址的字节存储区中,
编程统计其中负数的个数 。
例【4 - 3 2 】程序在本例中,用到了三个寄存器,这三个寄存器的功能分别是:
AX:累加器,用来累加 BUF中负数的个数,初值为 0
BX:地址寄存器,用来指示 BUF的地址,初值为 BUF的首地址
CX:计数器,用计数方式控制循环何时结束,初值为 BUF的长度 N
4.2.5 循环程序设计如何控制循环是循环程序设计中的一个重要环节,下面介绍最常见的两种循环控制方法:计数控制和条件控制一,计数控制当循环次数已知时,通常使用计数控制,计数控制又有正计数和倒计数两种形式
① 倒计数先将循环次数 N送入循环计数器中,每循环 1
次,计数器减 1,直到循环计数器中的内容为 0时结束循环下面以例 【 4-32】 的代码段为例说明这个问题 。
LEA BX,BUF
MOV CX,N ; 初始化部分
MOV AX,0
CYCLE,CMP BYTE PTR[BX],0
JGE NEXT ; 工作部分
INC AX
NEXT,INC BX
DEC CX ; 修改部分
JNZ CYCLE ; 控制部分
4.2.5 循环程序设计
② 正计数先将 0送入循环计数器中,每循环 1次,
计数器加 1,直到循环计数器中的内容与循环次数 N相等时结束循环下面将例 【 4-32】 的代码段改写为用
CX进行正计数来说明这个问题
LEA BX,BUF
MOV CX,0 ; 初始化部分
MOV AX,0
CYCLE:CMP BYTE PTR[BX],0
JGE NEXT ; 工作部分
INC AX
NEXT,INC BX
INC CX ; 修改部分
CMP CX,N ; 控制部分
JNZ CYCLE
4.2.5 循环程序设计二、条件控制有些情况下,循环次数无法事先确定,但它与问题中的某些条件有关,这些条件可以通过指令来测试,如果测试的结果满足循环条件,则继续循环,否则结束循环例 【 4-33】 编程统计 AX中 1的个数。
【 分析 】
每次判断 AX的最低位,如果最低位为 1则 BL加 1;否则 BL不加 1。然后 AX逻辑右移 1位,左边补 0,在某一时刻 AX必然为 0。因此,可以将 AX
是否为 0作为条件控制循环例【4 - 3 3 】程序
4.2.6 子程序设计子程序设计是使程序模块化的一种重要手段 。 当设计一个比较复杂的程序时,将程序划分为若干个相对独立的模块,确定各模块的入口及出口参数,
为各模块分配不同的名字,对每一个模块编制独立的程序段 ( 即子程序 ),最后将这些子程序根据调用关系连成一个整体 。 这样既便于分工合作,又可避免重复劳动,节省存储空间,提高程序设计的效率和质量,使程序简洁,清晰,易读,便于修改和扩充
4.2.6 子程序设计一、定义子程序子程序的定义格式是:
子程序名 PROC [NEAR/FAR]

子程序名 ENDP
子程序也称为过程,PROC,ENDP是定义子程序时必须使用的保留字,PROC和 ENDP相当于一对括号,将子程序的指令包括在内 。 如果主程序和子程序位于同一代码段,则称为段内调用,此时在 PROC后可加 NEAR说明此子程序是近过程 。 如果主程序和子程序不在同一代码段,则称为段间调用,此时在
PROC后可加 FAR说明此子程序是远过程 。 如果 NEAR和 FAR都不写,系统默认该子程序是近过程
4.2.6 子程序设计二,子程序的调用和返回为了实现子程序的调用和返回,可使用子程序调用指令 CALL和返回指令 RET
1,子程序调用指令 CALL
子程序调用指令 CALL的格式是,CALL OPD。 根据 OPD寻址方式的不同,又分为直接调用和间接调用 。 因此,子程序调用指令 CALL共有 4种组合,见表 4-21
4.2.6 子程序设计对于段间间接调用,需要双字单元存放子程序的入口地址信息,第一个字单元中放子程序入口的偏移地址,第二个字单元中放子程序所在段的段首址,见表 4-22
2,返回指令 RET
RET指令通常作为子程序的最后一条指令,
用来控制 CPU返回到主程序的断点处继续向下执行,RET指令的语句格式及功能见表 4-23
4.2.6 子程序设计无论是段内返回还是段间返回,当 RET指令执行后,主程序的断点地址信息已送回到
IP,CS中,堆栈恢复了转子前的状态
RET指令的另一种格式是,RET N,其中 N
是偶数 。 该指令用来废除栈顶 N个无用的参数 。
其操作是在正常 RET操作之后再做 SP+N→SP
4.2.6 子程序设计三,调用子程序前后怎样保存和恢复寄存器如果在子程序中要用到某些寄存器 ( 或存储单元 ),就会破坏这些寄存器 ( 或存储单元 ) 在转子前原有的内容 。 当执行完子程序返回断点继续执行主程序时,只能以被破坏的现场为背景进行工作,这显然是不对的 。 因此,必须考虑现场的保存和恢复 。 一般情况下,在子程序的开始安排一些保存现场的指令,在子程序的返回指令之前再恢复现场 。
例如,若子程序 SUBP中改变了寄存器 AX,BX,CX的内容,
则在子程序的开始处将这些寄存器的内容入栈保存,在子程序的返回指令之前用出栈指令依次恢复,具体实现方法如下,
4.2.6 子程序设计四,主程序和子程序间的参数传递主程序在调用子程序之前,必须把需要子程序处理的原始数据传递给子程序,即为子程序准备入口参数 。 子程序对入口参数进行一系列处理之后得到处理结果,该结果必须送给调用它的主程序,即提供出口参数以便主程序使用 。 这种主程序为子程序准备入口参数,子程序为主程序提供处理结果的过程称为主程序和子程序间的参数传递 。 常用的参数传递方法有寄存器法,约定单元法和堆栈法三种,
本节主要讲解前两种方法
1.寄存器法寄存器法就是子程序的入口参数和出口参数都在约定的寄存器中。此法的优点是参数传递快,编程也较方便,且节省内存单元。但由于寄存器个数有限,
而且在处理过程中要经常使用寄存器,
如果要传递的参数很多,将导致无空闲寄存器供编写程序使用。所以寄存器法只适用于要传递参数较少的情况
4.2.6 子程序设计例 【 4-34】 寄存器法参数传递举例,编写子程序求两个数的最大公约数
【 分析 】
X和 Y中放着两个两个整数,在主程序中分别用寄存器 AX和 BX将这两个整数传递给计算这两个整数最大公约数的子程序 GCDP,子程序 GCDP将计算结果用寄存器 AX传回主程序,存放在 GCD中 。 这道题的核心是求两个整数最大公约数的子程序 GCDP,它用的是辗转相减法 。 当两个整数不相等时用大数减去小数,直到两个数相等为止 。 假定 X,Y的值分别为 32、
24,处理过程见表 4-24
4.2.6 子程序设计
2,约定单元法约定单元法是把入口参数和出口参数都在约定的存储单元中 。 此法的优点是每个子程序要处理的数据或送出的结果都有独立的存储单元,编写程序时不易出错 。 缺点是要占用一定数量的存储单元例 【 4-35】 用约定单元法重写例 【 4-34】,求两个整数最大公约数和最小公倍数
【 分析 】
数据段的变量 X,Y,GCD,LCM是约定的存储单元,这些存储单元主,子程序都可使用 。 参数存放在 X,Y中可由 GCDP子程序使用,子程序处理结束后将结果存入 GCD,主程序计算最小公倍数送
LCM,计算 X,Y 最 小 公 倍 数 的 方 法 是,
LCM=(X*Y)/GCD
例【4 - 3 5 】程序
4.2.6 子程序设计子程序也可以不带参数,只是完成某种功能 。 下面的程序是在屏幕上输出一个空行 。
NEWLINE PROC
PUSH AX
PUSH DX
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
POP DX
POP AX
RET
NEWLINE ENDP
4.2.7 常用的 DOS和 BIOS调用我们在编制汇编源程序时,常常希望能从键盘输入字符或在显示器上显示出程序运行的结果 。 但由于计算机机种的不同,外设型号的差异,控制它们工作的程序也会有差异 。
如果每次都需要我们根据自己的工作环境来设计控制这些外设工作的程序,则必须要先搞清楚与之有关的设备,电路,接口等各方面的问题,既复杂,效率又低,也没有通用性正确的做法是:把这些控制过程编写成程序,作为操作系统的一部分事先放在系统盘上,用户在需要时只要按规定的格式设置好参数,直接调用即可。这种方式叫做利用操作系统的标准功能调用进行输入 /输出。这样既便于操作系统对外设进行统一管理,也便于用户在编制程序时,不用考虑输入 /输出的控制细节,提高了工作效率,
使编制出来的程序更具有通用性
4.2.7 常用的 DOS和 BIOS调用
DOS提供了系统功能调用,编号从 0~ 57H,主要分为设备管理,文件管理,目录管理,及其它功能调用四大类在微机的只读存储器 ROM中的程序,一部分是 BASIC语言解释程序,另一部分是基本输入 /输出系统 BIOS。 BIOS的主要功能是驱动系统中所配置的常用外设,如显示器,键盘,
打印机,磁盘驱动器以及异步通信接口等,使程序员不必过多地关心这些设备具体的物理特性和逻辑结构细节 ( 如外设寄存器地址,命令及状态格式等 ),从而能方便地控制各种输入 /输出操作 。 与 DOS的设备管理系统功能调用相比,使用
BIOS能完成更复杂的输入 /输出操作表 4-25中列出了最常用的 DOS和 BIOS调用,更详细的内容要查阅有关的资料
4.3.1 80286相对 8086增加的指令
1,立即数入栈指令格式,PUSH nnnn,功能:将字立即数 nnnn压入堆栈
2,将所有寄存器的内容压入堆栈指令格式,PUSHA,功能:将 8个 16位通用寄存器的内容按 AX,CX,DX,BX,SP,BP,SI,DI的顺序入栈 。
4.3 32位微处理器的寻址方式与指令系统格式,POPA,功能:将从栈顶开始的 8个存储字依次弹出堆栈并按 DI,SI,BP,SP,BX,DX,CX,AX的顺序分别传送 。
4,扩充的带符号整数乘法指令格式 1,IMUL OPD,OPS
格式 2,IMUL OPD,OPS1,OPS2
其中,OPD是 16位通用寄存器,格式 1中的 OPS可以是 16位通用寄存器,字存储器,8或 16位立即数;格式 2中的 OPS1可以是 16位通用寄存器,字存储器,但不能为立即数;格式 2中的 OPS2只能为 8或 16位立即数
3.弹出堆栈指令功能:格式 1是 OPD乘以 OPS,将乘积送 OPD;
格式 2将 OPS1乘以 OPS2,乘积送 OPD
5.串输入指令格式 1,[REP]INS 目标串,DX
格式 2,[REP]INSB 格式 3,[REP]INSW
功能:以 DX中的值为外设端口地址,从此端口输入一字符存入由 ES:DI(或 EDI)所指的存储器中,且根据方向标志 DF和串操作的类型来修改 DI(或 EDI)的值,利用 REP前缀可以连续输入串字符存入存储器中,直到 CX(或 ECX)减到零为止其中,格式 1中的目标串为目标操作数的符号地址,该符号地址确定了目标操作数的属性 (字或字节 ),DX寄存器中的内容为外设端口地址 。 当符号地址的属性为字节时,则该指令每次读入一个字节,DI内容加 1或减 1;当符号地址的属性为字时,
则该指令每次读入一个字,DI内容加 2或减 2。 格式
2和格式 3中已确定了串操作的类型,并且不带操作数,INSB为字节串输入,INSW为字串输入
4.3.1 80286相对 8086增加的指令
6,串输出指令格式 1,[REP]OUTS DX,源串 格式 2:
[REP]OUTSB 格式 3,[REP]OUTSW
功能:该指令与串输入指令的操作刚好相反,该指令中 DS:SI(或 ESI)指向源串,以 DX中的值为外设端口地址 。 执行时根据 DF的值和源串的类型自动修改
SI(或 ESI)的内容,利用 REP前缀可以连续输出源串中的内容,直到 CX(或 ECX)减到零为止
4.3.1 80286相对 8086增加的指令
7,移位指令格式,SHL OPD,OPS ( 逻辑左移指令 )
SHR OPD,OPS ( 逻辑右移指令 )
SAL OPD,OPS ( 算术左移指令 )
SAR OPD,OPS ( 算术右移指令 )
ROL OPD,OPS ( 不带进位的循环左移指令 )
ROR OPD,OPS ( 不带进位的循环右移指令 )
4.3.1 80286相对 8086增加的指令
RCL OPD,OPS ( 带进位的循环左移指令 )
RCR OPD,OPS ( 带进位的循环右移指令 )
功能:这 8条指令的格式和 8086/8088的指令是相同的,区别是在 8086/8088的指令系统中 OPS只能是 CL或 1,在 80286指令系统 OPS
中可以是任一 8位立即数
8,装入地址指针指令格式,LDS OPD,OPS
LES OPD,OPS
其中,OPD为 16位或 32位 (80386)的通用寄存器,OPS为存储器 。
功能:将 OPS所指的 4或 6(80386)个内存单元中的 2个字或 3个字先后送给 OPD和相应的段寄存器中,LDS和 LES指令分别隐含 DS和 ES段寄存器 。
4.3.1 80286相对 8086增加的指令
4.3.2 80386的寻址方式和 80386相对
80286增加的指令
80386微处理器增加了 8个 32位的通用寄存器 (EAX,EBX,ECX,EDX,ESI,EDI,EBP和
ESP)和段寄存器 FS和 GS,不仅兼容 80286的 16
位寻址方式,还新增了 32位寻址方式 。 在这种寻址方式下,有效地址由表中的 4个分量计算产生,见表 4-26。 当基址寄存器为 ESP或
EBP时默认的段寄存器为 SS,其它方式下默认的段寄存器均为 DS
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
1,直接寻址指令中给出的位移量就是有效地址
2,基址寻址以 8个 32位的通用寄存器中的任意一个作为基址寄存器形成操作数的有效地址
3,基址加位移寻址以 8个 32位的通用寄存器中的任意一个作为基址寄存器,再加上 8,16或 32位位移量形成操作数的有效地址
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
4,比例变址和位移寻址选取除 ESP外 7个通用寄存器中的任意一个作为变址寄存器,将其内容乘以比例常数,再加上 8、
16或 32位位移量,形成操作数的有效地址 5,基址加比例变址寻址以 8个 32位的通用寄存器中的任意一个作为基址寄存器,选取除 ESP外 7个通用寄存器中的任意一个作为变址寄存器,将变址寄存器的内容乘以比例常数,加上基址寄存器的内容形成操作数的有效地址
6,基址加比例变址加位移寻址有效地址 =基址 +(变址 ╳ 比例常数 )+位移量
80386相对 80286增加的指令有:
1.堆栈操作指令格式 1,PUSH OPS/POP OPD
扩展功能,PUSH指令可将 32位的 OPS压入堆栈;
POP指令可将栈顶的 2个字弹出给 32位的通用寄存器或
32位的存储器
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令格式 2,PUSH FS/PUSH GS/POP FS/POP GS中使用的 FS和 GS是 80386以上的微处理器增加的 2个附加段寄存器格式 3,PUSHA/PUSHAD/POPA/POPAD指令中操作数为隐含 。 PUSHA可以将全部 16位通用寄存器按 AX、
CX,DX,BX,SP,BP,SI,DI的顺序入栈; PUSHAD
可以将全部 32位通用寄存器按 EAX,ECX,EDX,EBX、
ESP,EBP,ESI,EDI的顺序入栈 。 POPA/POPAD则弹出由 PUSHA/PUSHAD保存的通用寄存器值,出栈顺序和上述的入栈顺序相反
2.地址指针传送指令格式,LFS OPD,OPS 功能,OPS先后装入
OPD和段寄存器 FS中,OPD为 16位或 32位通用寄存器格式,LGS OPD,OPS 功能,OPS先后装入
OPD和段寄存器 GS中,OPD为 16位或 32位通用寄存器格式,LSS OPD,OPS 功能,OPS先后装入
OPD和段寄存器 SS中,OPD为 16位或 32位通用寄存器
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
3,基本传送指令格式,MOV OPD,OPS 扩展功能,OPD和 OPS可以是 32位操作数,它要求 OPD和 OPS必须等长,否则必须用扩展传送指令 MOVZX和 MOVSX,这 2条指令只存在于 80386 以 上 的 微 处 理 器 中,格 式 为,
MOVZX/MOVSX OPD,OPS。 MOVZX为零扩展传送指令,
它将 OPS中的无符号数在高位加 0扩展成和 OPD等长,
然后传送给 OPD; MOVSX为符号扩展传送指令,它将
OPS中的带符号数在高位加 OPS的符号,扩展成和 OPD
等长,然后传送给 OPD
4.交换指令格式,SWAP OPD,OPS 扩展功能,32位的 OPD
和 OPS中的内容相互交换,不能同时为存储器数。
5,加法和减法指令格式 1:加法 ( ADD OPD,OPS/ADC OPD,OPS),减法
( SUB OPD,OPS/SBB OPD,OPS)
格式 2:加 1指令 ( INC OPD),减 1指令 ( DEC OPD)
扩展功能,OPD和 OPS均可为 32位通用寄存器或存储器数,不能同时为存储器数
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
6,乘法指令无符号乘法指令格式,MUL OPS
被乘数,OPS( 乘数 ) 和乘积的长度,位置见表 4-27。
其中,OPS和被乘数 (EAX)可为 32位通用寄存器或存储器数
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令带符号乘法指令格式 1,IMUL OPS。 功能和 MUL OPS基本相同,指令中的被乘数和乘数均认为是带符号数格式 2,IMUL OPD,OPS ; (OPD)*(OPS)→OPD
格式 3,IMUL OPD,OPS,立即数 ; (OPS)*立即数
→ OPD
格式 4,IMUL OPD,立即数 ; (OPD)*立即数 → OPD
规律:如果操作数多于一个,则后两个数相乘,
结果放在第一个操作数中
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
7,除法指令无符号除法指令 格式,DIV OPS
被除数,OPS( 除数 ) 和商的长度,位置见表 4-28
其中,OPS和被除数 (EDX:EAX)可为 64位通用寄存器或存储器数带符号除法指令格式,IDIV OPS
功能:和 DIV OPS基本相同,指令中的被除数和除数均认为是带符号数
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
8,比较指令格式,CMP OPD,OPS
扩展功能,OPD和 OPS可为 32位通用寄存器或存储器数,不能同时为存储器数,OPS也可为
32位立即数
9,求补指令格式,NEG OPD
扩展功能:将 32位的 OPD求补后送回到 OPD中
4.3.2 80386的寻址方式和 80386
相对 80286增加 的指令
10,逻辑指令格式,AND OPD,OPS ;逻辑与指令
OR OPD,OPS;逻辑或指令
XOR OPD,OPS ;逻辑异或指令
NOT OPD,OPS ;逻辑非指令
TEST OPD,OPS;逻辑测试指令扩展功能,OPD和 OPS可为 32位通用寄存器或存储器数,不能同时为存储器数,OPS也可为 32位立即数
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
11,移位指令格式 SHL OPD,OPS ( 逻辑左移指令 )
SHR OPD,OPS ( 逻辑右移指令 )
SAL OPD,OPS ( 算术左移指令 )
SAR OPD,OPS ( 算术右移指令 )
ROL OPD,OPS ( 不带进位的循环左移指令 )
ROR OPD,OPS ( 不带进位的循环右移指令 )
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
RCL OPD,OPS ( 带进位的循环左移指令 )
RCR OPD,OPS ( 带进位的循环右移指令 )
扩展功能,OPD可扩充为 32位通用寄存器或存储器数,
OPS可以是任一 8位立即数或 CL
12,串传送指令格式,[REP]MOVSD
扩展功能:将 DS段由 ESI作为指针的源串中的一个双字传送到 ES段由 EDI作为指针的目标串中,并根据 DF标志使 ESI
和 EDI加 4或减 4,如果带有重复前缀 REP,则重复执行这一传送,直到 ECX的内容减到零为止
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
13,串扫描指令格式,[REPZ/REPNZ]SCANSD 目标串功能:以 ES:EDI指向目标串的首地址,每执行一次则扫描目标串的一个双字是否与 EAX中的内容相等,如果相等则置 ZF=1,否则置 ZF=0。 每扫描一次 EDI都要按 DF的值自动加 4或减 4。
若加上前缀 REPZ/REPE,则表示未扫描完 ( ECX
不为零 ),且由 EDI所指的串元素与 EAX的值相等
( ZF=1) 则继续扫描;如果 ZF=0或 ECX=0则停止扫描
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令若加上前缀 REPNZ/REPNE,则表示未扫描完 ( ECX
不为零 ),且由 EDI所指的串元素与 EAX的值不相等
( ZF=0) 则继续扫描;如果 ZF=1或 ECX=0则停止扫描 。
若加上前缀 REPZ/REPNZ,每扫描一次 ECX减 1。
14,串比较指令格式,[REPZ/REPNZ]CMPSD 目标串,源串功能:将 DS:ESI所指源串中的双字与 ES:EDI所指目标串中的双字比较,如果相等则置 ZF=1,否则置
ZF=0。每扫描一次,EDI都要按 DF的值自动加 4或减
4
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令若加上前缀 REPZ/REPE,则在串未比较完 ( ECX不为零 ) 且两串中的元素相等 ( ZF=1) 的情况下继续比较,当遇到第一个不相等的元素 ( 此时 ZF=0) 或
ECX=0则停止比较 。
若加上前缀 REPNZ/REPNE,则在串未比较完
( ECX不为零 ) 且两串中的元素尚无一次比较是相等 ( 即 ZF=0) 的情况下继续比较,当遇到第一个相等的元素 ( 此时 ZF=1) 或 ECX=0则停止比较 。
若加上前缀 REPZ/REPNZ,每扫描一次 ECX减 1
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
15,串装入指令格式,LODSD
功能:将 DS:ESI所指源串中的一个双字装入 EAX中,
同时 ESI按 DF的值自动加 4或减 4。
16,串存储指令格式,[REP]STOSD
功能:将 EAX中的值存入 ES:EDI所指目标串中,
同时 EDI按 DF的值自动加 4或减 4。 若加上前缀 REP,
每存储一次 ECX减 1,直到 ECX为零时结束 。
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
17,串输入指令格式,[REP]INSD
功能:从 DX给出的端口地址读入一个双字存入由 ES:EDI所指的目标串中,且根据方向标志 DF来修改 EDI的值 ( 加 4或减 4),利用 REP前缀可连续输入双字并存入目标串中,每输入一次 ECX减 1,直到
ECX减到零为止
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
18,串输出指令格式,[REP]OUTSD
功能:将 DS:ESI 所指的目标串中的一个双字输出到 DX给出的端口,且根据方向标志 DF来修改
ESI的值 ( 加 4或减 4),利用 REP前缀可连续输出,
每输出一次 ECX减 1,直到 ECX减到零为止
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
19,循环指令格式 1,LOOP 目标格式 2,LOOPZ/LOOPE 目标格式 3,LOOPNZ/LOOPNE 目标其中,目标必须是短地址标号,这三种格式都使用 ECX作计数器
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令功能:对于格式 1,若 ECX的值减 1后不为 0,
则作短转移,否则退出循环向下执行 。 对于格式 2,若 ECX的值减 1后不为 0且 ZF=1,则作短转移,否则若 ECX的值为 0或 ZF=0,退出循环向下执行 。 对于格式 3,若 ECX的值减 1后不为 0且 ZF=0,则作短转移,否则若 ECX的值为 0
或 ZF=1,退出循环向下执行
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
20,无条件转移指令格式,JMP 目标扩展功能:若为近转移 ( NEAR),目标可为
32位的寄存器或存储器;若为远转移 ( FAR),目标可为一个立即数 ( 选择子,偏移量 ) 或存储器中的一个 48位的地址指针,即由 16位选择子和 32位偏移量组成 。
21,调用指令格式,CALL 目标
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令扩展功能,CALL指令与 JMP指令类似,也有 FAR和
NEAR属性,它们的共同点是实现程序的转移,但
CALL指令只作暂时转移,调用子程序后还要返回断点处继续向下执行,CALL指令与 JMP指令的目标操作数相同 。
22,返回指令格式,IRETD
功能:从中断服务程序返回,将堆栈指针所指的原 EIP,CS和 EFLAGS的值依次弹出给 EIP,CS和
EFLAGS
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
23,条件字节设置指令格式,SET 条件,目标其中,条件是指令助记符的一部分,是 SET指令所测试的内容,该条件与转移指令的条件相同,
目标只能为 8位的寄存器或存储器,保存测试的结果功能:若被测试条件成立,则将目标操作数置
1,否则置 0。 一般本指令前有影响标志位的 CMP和
TEST等指令
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
24,位测试和设置指令格式 1,BT OPD,OPS
功能:把目的操作数 OPD中由源操作数 OPS指定的位送 CF
标志格式 2,BTC OPD,OPS
功能,把目的操作数 OPD中由源操作数 OPS指定的位送 CF
标志,然后对那一位求反 。
格式 3,BTR OPD,OPS
功能,把目的操作数 OPD中由源操作数 OPS指定的位送 CF
标志,然后对那一位复位
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令
25,位扫描指令格式 1,BSF OPD,OPS
功能,向前位扫描指令 。 本指令从最低位 ( 第 0
位 ) 开始测试 OPS中的各位,当遇到有 1的位时,
ZF=0,且将该位的序号存入 OPD中,如果 OPS的所有位都是 0,则 ZF=1且 OPD中的值无意义
4.3.2 80386的寻址方式和 80386
相对 80286增加的指令注意,OPD必须为 16位或 32位的寄存器,OPS应为同类型的 16位或 32位的寄存器或存储器数格式 2,BSR OPD,OPS
功能,向后位扫描指令 。 本指令从最高位 ( 第
15位或第 31位 ) 开始测试 OPS中的各位,当遇到有 1
的位时,ZF=0,且将该位的序号存入 OPD中,如果
OPS的所有位都是 0,则 ZF=1且 OPD中的值无意义
4.3.3 80486相对 80386增加的指令
1.字节交换指令格式,BSWAP 目标其中,目标为 32位通用寄存器功能,若将 32位寄存器从低位到高位的顺序分为 0,1,2,3共 4个字节,则本指令将 0和 3字节交换,1和 4字节交换
4.3.3 80486相对 80386增加的指令
4.3.3 80486相对 80386增加的指令
2.比较并交换指令格式,CMPXCHG 目标,源其中,目标为 8/16/32位通用寄存器或存储器数,源为 8/16/32位通用寄存器功能:读出目标操作数并与累加器 AL/AX/EAX
的数据比较,如果相等,源操作数写入目标操作数中且 ZF=1;否则目标操作数替换累加器值且 ZF=0
3.交换并相加指令格式,XADD 目标,源
4.3.3 80486相对 80386增加的指令其中,目标为 8/16/32位通用寄存器或存储器数,
源为 8/16/32位通用寄存器功能,读出目标操作数与源操作数相加并送到目标操作数,还要将读出的目标操作数存入源操作数中
4,使高速缓存器中的数据全部无效指令格式,INVD
功能:使微处理器内部高速缓存器中的数据全部无效,且开始一个特殊的硬件总线周期,可用于使外部高速缓存器中的数据全部无效
4.3.3 80486相对 80386增加的指令
5,写回并使高速缓存无效指令格式,WBINVD
功能:使微处理器内部高速缓存器中的数据全部无效,并在外部缓存刷新总线周期之前产生一个特殊的回写总线周期,允许外部高速缓存将其内容写回主存
4.3.3 80486相对 80386增加的指令
6,使 TBL项无效指令格式,INVLPG 存储器功能:在实施页功能时,CPU把线性地址变换成物理地址,为了提高变换速度,将页表首先存入
CPU 的 转 换 后 援 缓 冲 器 TLB ( translation
lookaside buffer) 中,页部件的 TLB可保存 32个页表项,每个页表项由标记和页表数据两个字段组成,标记字段存有与页表项相对应的线性地址的位
32~位 12,页表数据字段存有页表项 。 若该指令所指示的存储器地址页的页表项处于 TLB中,则使该页表项无效
4.3.4 Pentium相对 80486增加的指令
1,条件传送指令格式,CMOV cc 目标,源功能:指令中 cc表示条件,以单个标志位或标志位的组合作为条件,
目标操作数限于 16位或 32位寄存器,源操作数可以是 16位或 32位寄存器或存储器 。 表 4-29列出了条件传送指令的条件及含义 。
2,8字节比较并交换指令 CMPXCHG8B
本指令是对 80486中 CMPXCHG指令的扩展,它用于比较两个 8字节数据,
将位于 EDX:EAX中的 64位数与存储器中的 64位数进行比较 。
4.4 32位汇编语言编程
4.4.1 汇编语言编程的两种格式一,简化段格式定义
.MODEL SMALL ;定义程序的存储模式,一般采用 SMALL
.STACK ;定义堆栈段,默认为 1024Byte
.386 ;程序中可使用 386指令
.DATA ;定义数据段,一般放具有初值的变量
┅ ;数据定义
.DATA? ;定义数据段,一般放不具有初值的变量
┅ ;数据定义
4.4.1 汇编语言编程的两种格式
.CODE ;定义代码段
.STARTUP ;程序启动点,包含完整格式的 MOV AX,DATA、
MOV DS,AX两条指令功能
┅ ;代码定义
.EXIT ;程序结束,相当于完整格式的 MOV AH,4CH、
INT 21H两条指令
END ;汇编结束
4.4.1 汇编语言编程的两种格式
1,存储模式伪指令存储模式决定一个程序的规模,也确定了进行子程序调用,指令转移和数据访问的缺省属性 。 当使用简 化 段 定 义格 式 书 写程 序 时,必 须 有存 储 模式,MODEL语句,MASM有 7种不同的存储模式,分别为:
① 微型模式 ( TINY)
用于创建扩展名为,COM的程序,文件长度在
64KB以下 。
② 小型模式 ( SMALL)
4.4.1 汇编语言编程的两种格式
③ 紧凑模式 ( COMPACT)
紧凑模式适合于数据量大但代码量小的程序
④ 中型模式 ( MEDIUM)
中型模式适合于数据量小但代码量大的程序
⑤ 大型模式 ( LARGE)
4.4.1 汇编语言编程的两种格式
⑥ 巨型模式 ( HUGE)
巨型模式和大型模式基本相同,只是静态数据不限制在 64KB以内
⑦ 平展模式 ( FLAT)
平展模式用于创建一个 32位的应用程序,
它只能运行在 32位的 X86 CPU上 。 该语句前要使用 32位 X86 CPU的说明伪指令 。 DOS下不能使用 FLAT模式,而编写 32位的 Windows 9X或
Windows NT程序时,则必须采用 FLAT模式
4.4.1 汇编语言编程的两种格式
1,简化段定义伪指令简化的段定义语句书写简短,语句,CODE,.DATA
和,STACK分别表示代码段,数据段和堆栈段的开始,
一个段的开始自动结束前面的一个段 。 在所有简化的段定义语句之前,必须有存储模式语句 SMALL
①,STACK[大小 ]
堆栈段伪指令,STACK创建一个堆栈段,段名是
STACK。 它的大小是指定堆栈所占存储区的字节数,
默认是 1024Byte( 1KB)
4.4.1 汇编语言编程的两种格式
②,DATA,.DATA?
数据段伪指令,DATA创建一个数据段 。 它用于定义具有初值的变量,也允许定义无初值的变量 。
无初值的变量可以安排在,DATA? 中,使用,DATA?
伪指令可以减小形成的 EXE文件长度,并与其他语言保持最大的兼容性
③,CONST伪指令用于建立常量数据段
④,CODE[段名 ]
.CODE伪指令用于建立一个代码段
4.4.1 汇编语言编程的两种格式
3,程序开始伪指令,STARTUP
.STARTUP 伪指令按照给定的 CPU 类型,根据,MODEL语句选择的存储模式,操作系统和堆栈类型,产生程序开始执行的代码,同时还指定了程序的启动地址 。 在 DOS下,,STARTUP伪指令还将初始化 DS值,调整 SS和 SP值 。
4,程序终止伪指令,EXIT[返回码 ]
.EXIT伪指令产生终止程序执行并返回操作系统的指令代码 。 它的可选参数是一个返回的数码,
通常用 0表示没有错误,例如,,EXIT 0对应的代码是,MOV AX,4C00H 和 INT 21H
4.4.1 汇编语言编程的两种格式
5,汇编结束伪指令 END[标号 ]
END伪指令指示汇编程序 MASM到此结束汇编过程,源程序的最后必须有一条 END语句,可选的标号用于指定程序的启动地址
4.4.2 32位汇编语言编程一,顺序程序设计例 【 4-37】 在一个表格中,存放着 0到 9十个数字的立方值,编程从键盘输入 0到 9之间的任意一个数,查表找出这个数的立方值 。
例【4 - 3 7 】程序二、分支程序设计 (选择结构 )
.IF 条件表达式分支体
[.ELSEIF 条件表达式分支体 ]
[.ELSE
分支体 ]
.ENDIF
4.4.2 32位汇编语言编程其中,方括号内的部分为可选项,分支体是汇编指令,条件表达式是变量,常量,寄存器等用操作符连接在一起生成的表达式 。 条件表达式中可用的操作符见表 4-30
操作符的优先关系见表 4-31,编号越小,优先级越高 。 其中,&”是位测试操作符,它的格式是:
数值表达式 &位数 。 圆括号,( ),可以用来改变运算的优先级
4.4.2 32位汇编语言编程例 【 4-38】 编程实现符号函数例【4 - 3 8 】程序
4.4.2 32位汇编语言编程例 【 4-39】 对一个班同学的成绩进行分类,分类标准见表 4-32。 这是一个多分支的例子,
MASM6.X没有提供类似于 C 语言中的 switch 或
PASCAL语言中的 case多分支结构,但可用 IF,
ELSE,ELSEIF嵌套来实现例【4 - 3 9 】程序
4.4.2 32位汇编语言编程三,循环程序设计
MASM6.X提供了类似高级语言的循环控制伪指令,它们是:
.WHILE/.ENDW,用于先判断,再执行的方式
.REPEAT/.UNTIL 与,REPEAT/.UNTILCXZ,用于先执行,再判断的方式
.BREAK,无条件退出循环
.CONTINUE,终止本次循环,开始下一次循环
4.4.2 32位汇编语言编程
1.,WHILE/.ENDW
.WHILE/.ENDW伪指令的格式是:
.WHILE 条件表达式循环体
.ENDW
例 【 4-40】 已知有 N个数据存放在以 ARRAY为首地址的双字存储区中,编程统计其中负数的个数
4.4.2 32位汇编语言编程例【4 - 4 0 】程序
2.,REPEAT/.UNTIL
.REPEAT/.UNTIL伪指令的格式是:
.REPEAT
循环体
.UNTIL 条件表达式例 【 4-41】 用,REPEAT/.UNTIL模式改写例 【 4-40】 。
【 程序 】 只写出代码段
4.4.2 32位汇编语言编程例【4 - 4 1 】程序
3.,REPEAT/.UNTILCXZ模式
.REPEAT/.UNTILCXZ伪指令的格式是:
.REPEAT
循环体
.UNTILCXZ [条件表达式 ]
例 【 4-42】 用,REPEAT/.UNTILCXZ模式改写例
【 4-40】
【 程序 】 只写出代码段
4.4.2 32位汇编语言编程例【4 - 4 2 】程序4.,BREAK
格式 ①,,BREAK[.IF条件表达式 ]
功能:当条件表达式为真时无条件退出当前循环格式 ②,BREAK
功能:无条件退出当前循环例 【 4-43】 编程找出满足 1+2+3+… +N之和大于或等于 2500时的最小自然数 N
4.4.2 32位汇编语言编程
5.,CONTINUE
格式 ①,,CONTINUE[.IF条件表达式 ]
功能:当条件表达式为真时终止本次循环,开始下一次循环格式 ②,CONTINUE,无条件终止本次循环,
开始下一次循环 。
例 【 4-44】 使用,WHILE/.ENDW和,CONTINUE改写例 【 4-40】
例【4 - 4 3 】程序例【4 - 4 4 】程序
4.4.2 32位汇编语言编程四,子程序设计例 【 4-45】 用辗转相减法求两个整数的最大公约数
.MODEL SMALL
.386
.STACK
.DATA
X DW 32
Y DW 24
.DATA?
GCD DW?
4.4.2 32位汇编语言编程
.CODE
.STARTUP
MOV AX,X
MOV BX,Y
CALL GCDP
MOV GCD,AX
.EXIT
GCDP PROC
4.4.2 32位汇编语言编程
.WHILE AX != BX
.IF AX > BX
SUB AX,BX
.ELSE
SUB BX,AX
.ENDIF
.ENDW
RET
GCDP ENDP
END