第 3章 指令系统与汇编语言本章主要教学内容
1,8086指令系统的寻址方式、指令 格式及应用
2,汇编语言基本格式、程序设计步骤和方法
3,顺序、分支、循环、子程序的基本结构和设计方法
4,DOS和 BIOS中断调用本章教学目的使学生掌握指令系统及其应用,学会程序设计的方法。
教学重点,指令系统的应用、汇编语言程序设计教学难点,指令的寻址方式、程序设计技巧第 3章 指令系统与汇编语言
3.1 寻址方式
3.2 8086指令系统
3.3 汇编语言简述
3.4 汇编语言程序设计
3.5 DOS和 BIOS中断调用
3.1 寻址方式
3.1.1 基本概念
1,指令系统与指令格式计算机可以执行的各种操作命令称为指令 。 通常一条指令对应一种基本操作,例如加,减,传送,
移位等 。 计算机所能执行的全部命令的集合即为该计算机的指令系统 。
计算机指令是完成特定操作的命令,CPU能直接识别和执行的指令是用二进制代码表示的,这种代码称为机器代码 。
计算机中的指令由操作码字段和操作数字段两部分组成 。
( 1) 操作码字段说明计算机要执行的具体操作,如传送,运算,移位,跳转等操作,是指令中必不可少的组成部分 。
( 2) 操作数字段说明在指令执行的过程中需要的操作数,它可以是操作数本身,也可以是操作数地址或是地址的一部分,还可以是指向操作数的地址指针或其它有关操作数据的信息 。 单地址指令的操作只需一个操作数,如加 1指令,INC AX。 大多数运算型指令都需要两个操作数,如加法指令,ADD AX,BX ;
运算的结果送到 AX中,AX称为目的操作数,BX称为源操作数 。
2,寻址及寻址方式的概念计算机中的指令有些不需要操作数,大多数指令采用一个或两个操作数 。 一般来说,操作数可以跟随在指令操作码之后,称为立即数;操作数也可以存放在 CPU内部的寄存器中,称为寄存器操作数;绝大多数的操作数存放在内存储器中,称为存储器操作数 。 指令指定操作数的位置,
即给出地址信息,在执行时需要根据这个地址信息找到需要的操作数 。 这种寻找操作数的过程称为寻址,而寻找操作数的方法称为寻址方式 。
3.1.2 8086指令系统的寻址方式
1,立即寻址立即寻址方式中,指令操作码和操作数都在存储器代码段中 。
汇编格式,n( n为立即操作数,是用 8位或 16位二进制补码表示的有符号数 )
功能:操作数存放在存储器,指令下一单元的内容为立即操作数 n。
图形表示如右:
2,寄存器寻址寄存器寻址方式的操作数在指令指明的寄存器中 。
汇编格式,R 其中 R表示寄存器名 。
功能:操作数直接存放在寄存器 R中 。
图形表示:
R
指令 → 操作数
3,存储器寻址如果操作码所需操作数存放在内存储器中,则指令中需要给出操作数的地址信息。为了提高程序的灵活性,
8086指令系统提供了多种存储器寻址方式。
( 1)直接寻址
( 2)寄存器间接寻址
( 3)寄存器相对寻址
( 4)基址变址寻址
( 5)与 I/O端口有关的寻址方式
( 1) 直接寻址汇编格式,① 含有变量的地址表达式 。
② 段寄存器名,[EA] 。
功能:指令下一字单元的内容是操作数的偏移地址 EA。
图形表示:
( 2) 寄存器间接寻址寄存器间接寻址方式中,寄存器的内容为操作数的偏移地址 EA,操作数在存储器中 。
汇编格式,[R]
功能:操作数存放在存储器,寄存器 R存放操作数的偏移地址 EA。
寄存器间接寻址示意图:
例如,MOV AX,[BX]
若 ( DS) = 2000H,( BX) = 1000H,物理地址= 20000H+
1000H= 21000H。 指令执行前,( AX) = 2030H,( 21000H)
= 0A0H,( 21001H) = 50H,指令执行后,( AX) = 50A0H,
( 21000H) = 0A0H,( 21001H) = 50H。 指令执行情况如下:
AX
AH AL
数据段 物理地址
A 0 H 21000H
50H 20001H
56H 20002H
偏移地址 EA计算方法如下:
EA=
[SI] SI作间址寄存器。
[DI] DI作间址寄存器。
[BX] BX作间址寄存器。
[BP] BP作间址寄存器。
( 3) 寄存器相对寻址寄存器相对寻址方式是在指令中给定一个基址寄存器 ( 或变址寄存器 ) 名和一个 8位或 16位的相对偏移量,
两者之和作为操作数的有效地址 。 对 BX,SI,DI这三个间址寄存器,指示的是数据段中的数据,而用 BP作间址寄存器,则指示的是堆栈段中的数据 。
汇编格式,X[R]( X表示位移量,是 8位或 16位二进制补码表示的有符号数 ) 。
功能:操作数存放在存储器,寄存器 R的内容加位移量 X
为操作数的偏移地址 EA。
偏移地址 EA计算方法如下,
( 4) 基址变址寻址基址变址寻址方式是在指令中给出一个基址寄存器名和一个变址寄存器名,两者内容之和作为操作数的有效地址 。 基址寄存器为 BX或 BP,变址寄存器为 SI或 DI,但指令中不能同时出现两个基址寄存器或两个变址寄存器 。 如果基址寄存器为 BX,则段寄存器使用 DS; 如果基址寄存器用
BP,则段寄存器用 SS。
汇编格式,[BR+IR]
功能:操作数存放在存储器,BR的内容加 IR的内容加位移量 X是操作数的偏移地址 EA。
操作数偏移地址 EA计算方法如下
【例】 MOV AL,[BX+ SI]( MOV AL,[BX][SI])
若指令执行前,( DS)= 1000H,( BX)= 0010H,
( SI)= 0002H,( 10012H)= 45H
则 EA=( BX)+( SI)= 0012H,PA=( DS)× 10H
+ EA= 10012H
指令执行后( AL)= 45H。
( 5) I/O端口寻址方式
( 1) 直接端口寻址直接端口寻址是在指令中直接给出要访问的端口地址,一般采用 2位十六进制数表示,也可以用符号表示,可访问的端口范围为 0~ 255。
例如,IN AL,25H
表示从 I/O端口地址为 25H的端口中取数据送到寄存器 AL中 。
( 2) 寄存器间接端口寻址若访问的端口地址值大于 255,则必须用 I/O端口的间接寻址方式 。 它是把 I/O端口的地址先送到 DX中,用 DX作为间接寻址寄存器 。 此种方式可访问的端口范围为 0~ 65535。
例如,MOV DX,285H ; 将端口地址 285H送到 DX寄存器
OUT DX,AL ; 将 AL中的内容输出到 DX指定的端口
3.2 8086指令系统
8086CPU指令系统按功能可以分为以下 6类指令:
● 数据传送类指令
● 算术运算类指令
● 逻辑运算 ( 位操作 ) 类指令
● 串操作类指令
● 控制转移类指令
● 处理器控制类指令
3.2.1 数据传送类指令
1 通用数据传送指令
2 累加器专用传送指令
3 地址传送指令
4 标志寄存器传送指令
1,通用数据传送指令
( 1) 传送指令 MOV
( 2) 堆栈指令 PUSH/ POP
( 3) 数据交换指令 XCHG
( 1)传送指令 MOV
语句格式,MOV OPD,OPS
功能:将源操作数传送入目的地址,源地址内容不变。
即( OPS) →OPD 。
下图描述了 MOV指令在传送数据时允许传送的路径及类型。
图 MOV指令所允许的数据传送路径及类型
MOV指令的形式有如下几种:
1) 从通用寄存器到通用寄存器 MOV reg1,reg2
2) 立即数传送到通用寄存器 MOV reg,data
3) 通用寄存器和存储单元之间
MOV mem (reg),reg (mem)
4) 立即数传送到存储单元 MOV mem,data
5) 段寄存器与通用寄存器间的数据传送
MOV seg,reg 或 MOV reg,seg
6) 段寄存器与存储单元间的数据传送
MOV seg,mem 或 MOV mem,seg
【例】 存储器与寄存器间数据传送。
MOV AX,BUF ; BUF是变量,源操作数为直接寻址
MOV BH,[DI] ; 源操作数为寄存器间接寻址
MOV DI,ES,3[SI] ; 源操作数为变址寻址,使用跨段前缀
MOV BP,3[BX+SI] ; 源操作数为基址加变址寻址
MOV BUFA,DL ; BUFA是一字节变量
MOV [BP],AX ; 使用 SS段寄存器
MOV DS,[BP],DL ; 使用跨段前缀
MOV BUF,DS ; BUF是个字变量
MOV ES,BUF
2.数据交换指令 XCHG
语句格式,XCHG OPD,OPS
功能:将源地址与目的地址中的内容互换 。 即 ( OPD) →OPS,
( OPS) →OPD 。
【 例 】 寄存器与存储器之间数据交换 。
MOV AX,5678H ; ( AX) =5678H
MOV BX,0FFFFH ; ( BX) =0FFFFH
XCHG AX,BX ; ( AX) =0FFFFH,( BX) =5678H
( 2) 堆栈操作指令
1) 进栈指令 PUSH
2) 出栈指令 POP
1)进栈指令 PUSH
语句格式,PUSH OPS
功能:将寄存器,段寄存器或存储器中的一个字数据压入堆栈,堆栈指针减 2。
即,① ( SP) -1 →SP ( OPS) 15~8→[SP]
② ( SP) -1 →SP ( OPS) 7~0→[SP]
2)出栈指令 POP
语句格式,POP OPD
功能,将栈顶元素弹出送至某一寄存器,段寄存器
( 除 CS外 ) 或存储器,堆栈指针加 2。
从 POP指令功能可看出,该指令为 PUSH指令的逆过程 。
即,① ( [SP]) → ( OPD) 7~0 ( SP) +1 →SP
② ( [SP]) → ( OPD) 15~8 ( SP) +1 →SP
2.累加器专用传送指令
( 1)输入指令 IN
输入指令用来从指定的外设寄存器取信息送入累加器 。 它有四种形式:
语句格式,IN AL,PORT
功能,( PORT) →AL
语句格式,IN AX,PORT
功能,( PORT) →AX
语句格式,IN AL,DX
功能,( [DX]) →AL
语句格式,IN AX,DX
功能,( [DX]) →AL
( 2)输出指令 OUT
输出指令用来把累加器的内容送往指定的外设存储器,它有四种形式:
语句格式,OUT PORT,AL
功能,( AL) → PORT
语句格式,OUT PORT,AX
功能,( AX) → PORT
语句格式,OUT DX,AL
功能,( AL) → [DX]
语句格式,OUT DX,AX
功能,( AX) → [DX]
( 2)查表转换指令 XLAT
语句格式,XLAT OPS或 XLAT
功能:将 ( BX) 为首址 ( AL) 为位移量的字节存储单元中的数据送 AL寄存器 。
即 ( [BX+AL]) →AL 。
3 地址传送指令
( 1)传送有效地址指令 LEA
语句格式,LEA OPD,OPS
功能:主存按源地址的寻址方式计算偏移地址,
将偏移地址送入指定寄存器 。
【 例 】 主存偏移地址的获取 。
MOV BX,0100H ; ( BX) =0100H
MOV SI,0210H ; ( SI) =0210H
LEA BX,1234[BX+SI]; ( BX) =1544H
( 2)传送有效地址及数据段首址指令 LDS
语句格式,LDS OPD,OPS
功能:将主存中指定字单元数据送入指定存储器,下一字单元数据送 DS寄存器 。
( 3)传送有效地址及附加数据段指令 LES
语句格式,LES OPD,OPS
功能:将主存某字单元内容送指定寄存器 。
即 ( OPS) →OPD,( OPS+2) →ES 。
4 标志寄存器传送指令
( 1)标志送 AH指令 LAHF
语句格式,LAHF
功能:将标志寄存器的低 8位送入 AH寄存器 。
即 ( FLAGS) 7-0→AH 。 该指令的执行对标志位无影响 。
【 例 】 标志寄存器传送 。
执行前,( FLAGS) =0485H,( AX) =0FFFFH
执行指令,LAHF
( 2) AH送标志指令 SAHF
语句格式,SAHF
功能:将 AH的内容送入标志寄存器的低 8位,高
8位不变 。 即 ( AH) →FLAGS 7-0.。
从该指令功能可看出,SAHF为 LAHF的逆过程。
( 3)标志寄存器进栈指令 PUSHF
语句格式,PUSHF
功能:将标志寄存器的内容压入堆栈 。
即 ( FLAGS) →↓ ( SP) 。
( 4) 标志寄存器出栈指令 POPF
功能,将栈顶内容弹出送入标志寄存器中 。 即 ↑ ( SP) →FLAGS 。
POPF指令与 PUSHF指令互为逆过程 。
3.2.2 算术运算类指令
1 加法类指令
2 减运算指令
3 乘运算指令
4 除运算指令
5 BCD码调整指令
1 加法运算指令
( 1) 不带进位 加 法 指令 ADD
( 2) 带进位加指令 ADC
( 3) 加 1指令 INC
( 1) 不带进位加指令 ADD
语句格式,ADD OPD,OPS
功能:将目的操作数与源操作数相加,结果存入目的地址中,源地址的内容不改变 。
即 ( OPD) +( OPS) →OPD 。
( 2) 带进位加法指令 ADC
语句格式,ADC OPD,OPS
功能:将目的操作数加源操作数再加低位进位,
结果送目的地址 。
即 ( OPD) +( OPS) +CF → OPD。
【 例 】 无符号双字加法运算 。
MOV AX,4652H ; ( AX) =4652H
ADD AX,0F0F0H ; ( AX) =3742H,CF=1
MOV DX,0234H ; ( DX) =0234H
ADC DX,0F0F0H ; ( DX) =0F325H,CF=0
( 3) 加 1指令 INC
语句格式,INC OPD
功能:将目的操作数加 1,结果送目的地址 。 即
( OPD) +1→OPD 。
INC指令是一个单操作数指令,操作数可以是寄存器或存储器操作数 。
如,INC BX,即 ( BX) +1→BX 。
加 1指令可用于对计数器和地址指针进行调整。
2 减法运算指令
( 1) 不带借位减法指令 SUB
( 2) 带借位减指令 SBB
( 3) 减 1指令 DEC
( 4) 求补指令 NEG
( 5) 比较指令 CMP
( 1) 不带借位减法指令 SUB
语句格式,SUB OPD,OPS
功能:目的操作数减源操作数,结果存于目的地址,
源地址内容不变 。
即 ( OPD) - ( OPS) →OPD
【 例 】 减法运算 。
MOV AX,5678H; ( AX) =5678H
SUB AX,1234H; ( AX) =4444H
MOV BX,3354H; ( BX) =3354H
SUB BX,3340H; ( BX) =0014H
( 2) 带借位减指令 SBB
语句格式,SBB OPD,OPS
功能:目的操作数减源操作数再减低位借位 CF,结果送目的地址 。
即 ( OPD) ― ( OPS) ―CF → OPD
( 3) 减 1指令 DEC
语句格式,DEC OPD
功能:将目的操作数减 1,结果送目的地址 。 即
( OPD) - 1→OPD 。
DEC指令是一个单操作数指令,操作数可以是寄存器或存储器操作数 。
如,DEC CX。 即 ( CX) - 1→CX 。
减 1指令 DEC也一般用于对计数器和地址指针的调整 。
( 4) 求补指令 NEG
语句格式,NEG OPD
功能:将目的操作数的每一位求反 ( 包括符号位 ) 后加 1,
结果送目的地址 。
即 ( OPD) +1→OPD 。
【 例 】 求补运算 。
MOV AX,0FF64H
NEG AL ; ( AX) =0FF9CH
SUB AL,9DH ; ( AX) =0FFFFH
NEG AX ; ( AX) =0001H
DEC AL ; ( AX) =0000H
NEG AX ; ( AX) =0000H
( 5) 比较指令 CMP
语句格式,CMP OPD,OPS
功能:目的操作数减源操作数,结果只影响标志位,不送入目的地址 。
即 ( OPD) - ( OPS) 。
【 例 】 比较 AL的内容数值大小 。
CMP AL,50 ; ( AL) - 50
JB BELOW ; ( AL) <50,转到 BELOW处执行
SUB AL,50 ; ( AL) >=50,( AL) - 50→AL
INC AH ; ( AH) +1→AH
BELOW,…
3 乘法运算指令
( 1) 无符号数乘法指令 MUL
( 2) 有符号乘指令 IMUL
( 1)无符号数乘法指令 MUL
语句格式,MUL OPS
功能,若是字节数据相乘,( AL) 与 OPS相乘得到字数据存入 AX中;若是字数据相乘,则 ( AX) 与 OPS
相乘得到双字数据,高字存入 DX,低字存入 AX中 。
即字节乘法:( AL) * ( OPS) →AX,字乘法:
( AX) * ( OPS) →DX,AX
【例】无符号数 0A3H与 11H相乘 。
MOV AL,0A3H ; ( AL) =0A3H
MOV BL,11H ; ( BL) =11H
MUL BL ; ( AX) =0AD3H
( 2)有符号乘指令 IMUL
语句格式,IMUL OPS
功能:字节乘法,( AL) *( OPS) →AX,字乘法,( AX) *
( OPS) →DX,AX。
IMUL指令除计算对象是带符号二进制数外,其他都与 MUL一样,
但计算结果不同。
【例】有符号数 0B4H与 11H相乘。
MOV AL,0B4H ; ( AL) =B4H
MOV BL,11H ; ( BL) =11H
IMUL BL ; ( AX) =0FAF4H
4 除法运算指令
( 1) 无符号除指令 DIV
( 2) 有符号 除指令 IDIV
( 3) 符号扩展指令
( 1) 无符号除指令 DIV
语句格式,DIV OPS
功能:
字节除法 ( AX) /( OPS) → AL( 商 ),AH( 余数 )
字除法 ( DX,AX) /( OPS) → AX( 商 ),DX( 余数 )
【 例写出实现无符号数 0400H / 0B4H运算的程序段 。
MOV AX,0400H ; ( AX) =0400H
MOV BL,0B4H ; ( BL) =0B4H
DIV BL ; 商( AL) =05H,余数( AH) =7CH
( 2) 有符号除指令 IDIV
语句格式,IDIV OPS
功能:
字节除法,( AX) /( OPS) → AL( 商 ),AH( 余数 )
字除法,( DX,AX) /( OPS) → AX ( 商 ),DX( 余数 )
除法指令 DIV和 IDIV虽然对标志的影响未定义,但可产生溢出 。
【 例 】 写出实现有符号数 0400H /0B4H运算的程序段 。
MOV AX,0400H ; ( AX) =0400H
MOV BX,0B4H ; ( BX) =0B4H
IDIV BX ; ( AL) =0F3H,( AH) =24H
( 3) 符号扩展指令
1) 字节转换成字指令 CBW
语句格式,CBW
功能:将 AL中的符号位数据扩展至 AH。
【 例 】 将字节数据扩展成字数据 。
MOV AL,0A5H ; ( AL) =0A5H
CBW ; ( AX) =0FFA5H
ADD AL,70H ; ( AL) =25H
CBW ; ( AX) =0025H
2) 将字转换成双字指令 CWD
语句格式,CWD
功能:将 AX中的符号位数据扩展至 DX 。
【 例 】 将字数据扩展成双字数据 。
MOV DX,0 ; ( DX) =0
MOV AX,0FFABH ; ( AX) =0FFABH
CWD ; ( DX) =0FFFFH ( AX) =0FFABH
5 十进制调整指令
( 1) 加法的十进制调整指令 DAA
( 2) 减法的十进制调整指令 DAS
( 3) 加法的非压缩 BCD码调整指令 AAA
( 4)减 法的非压缩 BCD码调整指令 AAS
( 1)加法的十进制调整指令 DAA
语句格式,DAA
功能:如果 AL寄存器中低 4位大于 9或辅助进位 ( AF)
=1,则 ( AL) =( AL) +6且 ( AF) =1; 如果 ( AL)
>=0A0H或 ( CF) =1,则 ( AL) =( AL) +60H且 ( CF)
=1。 同时,SF,ZF,PF均有影响 。
【 例 】 压缩 BCD码的加法运算 。
MOV AL,68H ; ( AL) =68H,表示压缩 BCD码 68
MOV BL,28H ; ( BL) =28H,表示压缩 BCD码 28
ADD AL,BL ; 二进制加法,( AL) =68H+28H=90H
DAA ; 十进制调整,( AL) =96H; 实现压缩 BCD码加法,68+28=96
( 2)减法的十进制调整指令 DAS
语句格式,DAS
功能:如果 ( AF) =1或 AL寄存器中低 4位大于 9,则 ( AL) =
( AL) - 6且 ( AF) =1; 如果 ( AL) >=0A0H或 ( CF) =1,则
( AL) =( AL) - 60H且 ( CF) =1。 同时 SF,ZF,PF均受影响 。
【 例 】 压缩 BCD码的减法运算 。
MOV AL,68H ; ( AL) =68H,表示压缩 BCD码 68
MOV BL,28H ; ( BL) =28H,表示压缩 BCD码 28
SUB AL,BL ; 二 进 制 减 法,( AL) =68H-
28H=40H
DAS ; 十进制调整,( AL) =40H; 实现压缩 BCD码减法,68- 28=40
( 3) 加法的非压缩 BCD码调整指令 AAA
语句格式,AAA
功能:如果 AL的低 4位大于 9或 ( AF) =1,则:
( AL) =( AL) +6
( AH) =( AH) +1
( AF) =( CF) =1
且 AL高 4位清零 。
否则,( CF) =( AF) =0
AL高 4位清零 。
( 4) 减法的非压缩 BCD码调整指令 AAS
语句格式,AAS
功能:如果 AL的低 4位大于 9或 ( AF) =1,则:
( AL) =( AL) - 6
( AH) =( AH) - 1
( AF) =( CF) =1
AL高 4位清零 。
否则,( CF) =( AF) =0
AL高 4位清零 。
其他标志位 OF,PF,SF,ZF不确定 。
3.2.3 逻辑运算与移位指令
1 逻辑运算指令
2 移位指令
3 循环移位指令
1 逻辑运算指令
( 1) 求反指令 NOT
( 2) 逻辑乘指令 AND
( 3) 测试指令 TEST
( 4) 逻辑加指令 OR
( 5) 按位加指令 XOR
( 1) 求反指令 NOT
语句格式,NOT OPD
功能:将目的地址中的内容逐位取反后送入目的地址 。 即 ( OPD) →OPD
【 例 】 逻辑非运算 。
MOV AX,878AH ; ( AX) =878AH
NOT AX,; ( AX) =7875H
( 2) 逻辑乘指令 AND
语句格式,AND OPD,OPS
功能:将目的操作数和源操作数进行逻辑乘运算,
结果存目的地址 。
即 ( OPD) ∧ ( OPS) →OPD 。
该指令用于清除目的操作数中与源操作数置 0的对应位 。 说明:逻辑乘的运算法则为,1∧ 1=1,1∧ 0=0,
0∧ 1=0,0∧ 0=0
【 例 】 将 AL中第 3位和第 7位清零 。
MOV AL,0FFH
AND AL,77H
( 3) 测试指令 TEST
语句格式,TEST OPD,OPS
功能:源地址和目的地址的内容执行按位的逻辑乘运算,结果不送入目的地址 。
即 ( OPD) ∧ ( OPS) 。
【 例 】 测试 AX中的第 12位是否为 0,不为 0则转 L。
TEST AX,1000H
JNE L
( 4) 逻辑加指令 OR
语句格式,OR OPD,OPS
功能:将目的操作数和源操作数进行逻辑加运算,结果存目的地址 。
即 ( OPD) ∨ ( OPS) →OPD 。
说明:逻辑加的运算法则为,1∨ 1=1,1∨ 0=1,0∨ 1=1,
0∨ 0=0。
【 例 】 将 AL寄存器中第 3位和第 7位置 1。
MOV AL,0
OR AL,88H
( 5) 按位加指令 XOR
语句格式,XOR OPD,OPS
功能:目的操作数与源操作数做按位加运算,结果送入目的地址 。
即 ( OPD) ⊕(OPS) →OPD 。
说明:按位加的运算法则为; 1⊕ 1=0,1⊕ 0=1,0⊕ 1=1,
0⊕ 0=0。
【 例 】 按位加运算 。
MOV AL,45H ; ( AL) =45H
XOR AL,31H ; ( AL) =74H
2 移位指令移位指令包括算术移位指令,逻辑移位指令和循环移位指令,分别进行左移和右移操作 。 这些指令均有统一的语句格式:
[标号,]操作符 OPD,1或 [标号,]操作符 OPD,CL
其功能为将目的操作数的所有位按操作符规定的方式移动 1位或按寄存器 CL规定的次数 ( 0~ 255) 移动,
结果送入目的地址 。 目的操作数是 8位 ( 或 16位 ) 的寄存器数据或存储器数据 。
( 1) 算术左移和逻辑左移指令 SAL( SHL)
语句格式,SAL OPD,1 或 SHL OPD,1
SAL OPD,CL或 SHL OPD,CL
功能:将 ( OPD) 向左移动 CL指定的次数,最低位补入相应的0,CF的内容为最后移入位的值 。
( 2) 算术右移指令 SAR
语句格式,SAR OPD,1或 SAR OPD,CL
功能:将( OPD) 向右移动 CL指定的次数且最高位保持不变; CF的内容为最后移入位的值。
【 例 】 算术右移运算 。
MOV BH,0F4H ; ( BH) =0F4H
MOV CL,2 ; ( CL) =2
SAR BH,CL ; ( BH) =0FDH,( CF) =0
该例语句,SAR BH,CL”实际上完成了 ( BH)
/4 →BH 的运算,所以,用 SAR指令可以实现对有符号数除 2n的运算 ( n为移位次数 ) 。
( 3) 逻辑右移指令 SHR
语句格式,SHR OPD,1或 SHR OPD,CL
功能:将 ( OPD) 向右移动 CL规定的次数,最高位补入相应个数的0,CF的内容为最后移入位的值 。
3,循环移位指令
( 1) 循环左移指令 ROL
语句格式,ROL OPD,1或 ROL LPD,CL
功能:将目的操作数的最高位与最低位连成一个环,将环中的所有位一起向左移动 CL规定的次数 。 CF的内容为最后移入位的值 。
( 2) 循环右移指令 ROR
语句格式,ROR OPD,1或 ROR OPD,CL
功能:将目的操作数的最高位与最低位连成一个环,将环中的所有位一起向右移动 CL规定的次数,CF的内容为最后移入位的值 。
( 3) 带进位的循环左移指令 RCL
语句格式,RCL OPD,1或 RCL OPD,CL
功能:将目的操作数连同 CF标志一起向左循环移动 CL规定的次数。
( 4) 带进位的循环右移指令 RCR
语句格式,RCR OPD,1或 RCR OD,CL
功能:将目的操作数连同 CF标志一起向右循环移动所规定的次数。
3.2.4 串操作类指令串操作指令,
数据传送类指令每次只能传送一个数据,若要传送大批数据就需要重复编程,这样就浪费了大量的时间和空间。
为此 8086提供了一组处理主存中连续存放数据串的指令,这就是 串操作指令。
下面流程图总结了串操作的过程。
图 串操作流程图
1,传送指令 MOVS
语句格式,① MOVSB—— 字节串传送
② MOVSW—— 字串传送功能:将以 SI为指针的源串中的一个字节 ( 或字 )
存储单元中的数据传送至以 DI为指针的目的地址中去,并自动修改指针,使之指向下一个字节 ( 或字 )
存储单元 。
即,① ( DS,[SI]) →ES,[DI]。
② 当 DF=0时,( SI) 和 ( DI) 增量 。
当 DF=1时,( SI) 和 ( DI) 减量 。
2,串比较指令 CMPS
语句格式,① CMPSB—— 字节串比较
② CMPSW—— 字串比较功能:将 SI所指的源串中的一个字节 ( 或字 ) 存储单元中的数据与 DI所指的目的串中的一个字节 ( 或字 ) 存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存 。
即,① ( [SI]) - ( [DI]) 。
② 修改串指针,使之指向串中的下一个元素 。
当 DF=0时,( SI) 和 ( DI) 增量 。 当 DF=1时,( SI) 和 ( DI)
减量 。
3,串搜索指令 SCAS
语句格式,① SCASB—— 字节串搜索
② SCASW—— 字串搜索功能,AL( 字节 ) 或 AX( 字 ) 中的内容与 DI所指的目的串中的一个字节 ( 或字 ) 存储单元中的数据相减,根据相减结果设置标志位,结果不保存,
即,① 字节操作,( AL) - ( [DI]),字操作,( AX) -
( [DI]) 。
② 修改指针使之指向串中的下一个元素 。
当 DF=0时,( DI) 增量 。 当 DF=1时,( DI) 减量 。
4,从源串中取数指令 LODS
语句格式,① LODSB—— 从字节串中取数
② LODSW—— 从字串中取数功能:将 SI所指的源串中的一个字节 ( 或字 ) 存储单元中的数据取出来送入 AL( 或 AX) 中 。
即,① 字节 操作,( [SI]) →AL,字 操作,
( [SI]) →AX 。
② 修改指针 SI,使它指向串中的下一个元素 。
当 DF=0时,( SI) 增量。当 DF=1时,( SI) 减量。
5,往目的串中存数指令 STOS
语句格式,① STOSB—— 往字节串中存数
② STOSW—— 往字串中存数功能:将 AL或 AX中的数据送入 DI所指的目的串中的字节 ( 或字 ) 存储单元中 。
即,① 字节操作,( AL) →[DI],字操作,( AX)
→[DI] 。
② 修改指针 DI,使之指向串中的下一个元素 。
当 DF=0时,( DI) 增量 ) 。 当 DF=1时,( DI) 减量 。
6,重复前缀指令 REP REPZ REPNZ
( 1) REP
REP前缀用在 MOVS,STOS,LODS指令前 。
功能:每执行一次串指令 ( CX) - 1,直到 ( CX) =0,重复执行结束 。
( 2) REPZ
该指令一般用在 CMP,SCAS指令前 。
功能:每执行一次串指令 ( CX) - 1,并判断 ZF标志是否为 0,
只要 ( CX) =0或 ZF=0,则重复执行结束 。
( 3) REPNZ
该指令一般用在 CMPS,SCAS 指令前 。
功能:每执行一次串指令 ( CX) - 1,并判断 ZF标志是否为 0,
只要 ( CX) =0或 ZF=1,则重复执行结束 。
3.2.5 控制转移类指令
1 无条件转移指令
2 条件转移指令
3 循环控制指令
4 子程序调用指令
1 无条件转移指令表 无条件转移指令的语句格式及功能
2 条件转移指令
( 1) 简单条件转移指令
( 2) 无符号数条件转移指令
( 3) 有符号数条件转移指令它们都有通用的语句格式和功能 。
语句格式,[ 标号,] 操作符 短标号功能:
如果条件满足,则 ( IP) + 位移量 → IP。
( 1)简单条件转移指令
( 2) 无符号数条件转移指令无符号数条件转移指令表
【 例 】 比较无符号数大小,将较大的数存放
AX寄存器 。
CMP AX,BX ; ( AX) - ( BX)
JNB NEXT ; 若 AX>=BX,转移到 NEXT
XCHGAX,BX ; 若 AX<BX,交换
NEXT,…
( 3) 有符号数条件转移指令表:有符号数条件转移指令
【 例 】 比较有符号数大小,将较大的数存放在 AX寄存器 。
CMP AX,BX ; ( AX) - ( BX)
JNL NEXT ; 若 AX>=BX,转移到 NEXT
XCHG AX,BX ; 若 AX<BX,交换
NEXT,…
3,测试 CX的值为 0转移指令指令格式,JCXZ opr
测试条件:若 ( CX) = 0,则转移到指定位置 。
4,循环控制指令循环控制指令用于控制程序的循环,
其控制转向的目的地址是在以当前 IP内容为中心的- 128~ ﹢ 127的范围内,指令采用 CX作为计数器,每执行一次循环,
CX内容减 1,直到为 0,循环结实 。
8086指令系统中主要有三种循环控制语句 。
( 1) LOOP循环控制指令语句格式,LOOP 短标号功能,( CX) - 1 ≠ 0,则程序转移 ( 循环 ) ;
否则,顺序执行 。
说明:使用 LOOP指令可代替两条指令:
DEC CX
JNE 短标号
( 2) LOOPZ( LOOPE) 循环控制指令语句格式,① LOOPE 短标号
② LOOPZ 短标号功能,( CX) - 1 ≠ 0且 ZF=1,则程序转移 ( 循环 ) ;否则,顺序执行 。
( 3) LOOPNZ( LOOPNE) 循环控制指令语句格式,① LOOPNE 短标号
② LOOPNZ 短标号功能,( CX) - 1≠ 0,则程序转移
( 循环 ) ;否则,顺序执行 。
4,子程序调用和返回指令在软件设计过程中,通常把功能分解为若干个小的模块 。 每一个小功能模块对应一个过程 。 在汇编语言中,过程又称为子程序 。 程序中可由调用程序 ( 称为主程序 ) 调用这些子程序,子程序执行完毕后返回主程序继续执行 。
子程序调用分为段内和段间调用 。
指令格式为,CALL NEAR PTR opr ; 段内调用
CALL FAR PTR opr ; 段间调用
RET ; 子程序返回其中,opr为子程序名 ( 即子程序第一条指令的符号地址 ) 。
3.2.6 处理器控制类指令主要用于修改状态标志位,控制 CPU的功能如使 CPU暂停,等待,空操作等 。
1,标志位操作指令
( 1) 进位标志 CF设置指令
CLC,对 CF位清 0
STC,对 CF位置 1
CMC,对 CF位求反
( 2) 方向标志 DF设置指令
CLD,对 DF位清 0
STD,对 DF位置 1
( 3) 中断允许控制标志 IF设置指令
CLI,对 IF位清 0
STI,对 IF位置 1
2,其它 CPU控制指令
HLT,暂停指令
WAIT,等待指令
NOP,空操作指令
LOCK,封锁指令
ESC,交权指令
3.3 汇编语言简述
3.3.1 汇编语言语句格式
1,汇编语言和汇编程序的基本概念汇编语言是一种面向 CPU指令系统的程序设计语言,
它采用指令助记符来表示操作码和操作数,用符号地址表示操作数地址 。
汇编语言编写的源程序在输入计算机后,需要将其翻译成目标程序,计算机才能执行相应指令,这个翻译过程称为汇编,完成汇编任务的程序称为汇编程序 。
汇编程序是最早也是最成熟的一种系统软件,它除了能够将汇编语言源程序翻译成机器语言程序这一主要功能外,还能够根据用户的要求自动分配存储区域,包括程序区,数据区,
暂存区等;自动把各种进制数转换成二进制数,把字符转换成 ASCII码,计算表达式的值等;自动对源程序进行检查,
给出错误信息,如非法格式,未定义的助记符,标号,漏掉操作数等 。 具有这些功能的汇编程序称为基本汇编 ASM
( Assembler) 。
在基本汇编的基础上,进一步允许在源程序中把一个指令序列定义为一条宏指令,并包含有大量伪指令的汇编程序,叫做宏汇编 MASM( MacroAssembler) 。 它包含全部基本汇编
ASM的功能,还增加了宏指令,结构,记录等高级汇编语言功能 。
2,汇编语言语句格式汇编语言的语句可以由 1~4部分组成:
[名字 ] 操作符 [操作数 ] [;注释 ]
其中带方括号的部分表示任选项 。
( 1) 名字字段:名字是一个符号,表示本条语句的符号地址 。 名字可以是标号和变量,统称为标识符 。 它是由字母打头的字符串 。 在汇编语言程序中,
指令语句的名字之后要用冒号,,,,而伪指令语句中名字之后不要加冒号,,,。
标号和变量具备 3种属性:
段属性:该属性定义了标号和变量的段起始地址,其值必须在一个段寄存器中 。 标号的段是它所出现的对应代码段,由 CS指示 。
变量的段通常由 DS或者 ES指示 。
偏移属性:该属性表示标号和变量相距段起始地址的字节数,该数是一个 16位无符号数 。
类型属性:该属性对于标号而言,用于指出该标号是在本段内引用还是在其他段中引用 。 标号的类型有 NEAR( 段内引用 ) 和
FAR( 段间引用 ) 。 对于变量,其类型属性说明变量有几个字节长度,这一属性由定义变量的伪指令确定 。
( 2) 操作符字段:操作符可以是机器指令,伪指令和宏指令的助记符 。
机器指令是 CPU指令系统中的指令,汇编程序将其翻译成对应的机器码 。 伪指令则不能翻译成对应的机器码,它只是在汇编过程中完成相应的控制操作,又称为汇编控制指令 。 宏指令则是有限的一组指令 ( 机器指令,伪指令 ) 定义的代号,汇编时将根据其定义展开成相应的指令 。
( 3) 操作数字段:是操作符的操作对象 。 当有两个或两个以上的操作数时,各操作数之间用逗号隔开 。 操作数一般有常数,寄存器,标号,变量和表达式等几种形式 。
常数:常数是没有属性的纯数,它的值在汇编时已完全确定,
程序运行过程中,不会发生变化 。 常数通常被称为立即数,
它只能用作源操作数,不能作为目标操作数 。 它的允许取值范围由指令中的目标操作数的形式自动确定为 8位或 16位 。
存储器操作数:包括标号和变量 。 它可以作为源操作数,也可以作为目标操作数,但不能同时充当源操作数和目标操作数 。 标号是可执行的指令性语句的符号地址,它可以作为
JMP和 CALL指令的转向目标操作数 。 变量是指存放在某些存储单元中的数据,这些数据在程序运行期间是可以改变的 。
变量通过标识符来引用,可以作为存储器访问指令的源操作数和目标操作数 。
表达式:由常数,寄存器,标号,变量与一些运算符相结合而成,一般有数字表达式和地址表达式两种 。
( 4)注释字段:以“;”开头的说明部分,是语句的非执行部分,可以根据需要来写。一般情况下,注释用来说明一段程序或几条语句的功能,以增加程序的可读性,便于修改和调试。
3,汇编语言中的标识符,表达式和运算符
( 1) 标识符汇编语言语句格式第一个字段是它的名字字段,名字可以是标号或变量,这两者又称为标识符 。
( 2) 表达式和运算符在表达式中,运算符充当着重要的角色。 8086宏汇编有算术运算符、逻辑运算符、关系运算符、分析运算符和综合运算符共 5种。
3.3.2 汇编语言程序结构汇编语言源程序是分段结构形式 。 一个汇编语言源程序是由若干个逻辑段组成,每个逻辑段以 SEGMENT语句开始,以 ENDS语句结束 。
整个源程序以 END语句结束 。 每个逻辑段内有若干条语句,一个汇编源程序是由完成某种特定操作功能的语句组成的 。
通常,一个汇编源程序一般应该由 3个逻辑段组成,即数据段,堆栈段和代码段 。
( 1) 数据段用来在内存中建立一个适当容量的工作区,以存放常数,变量等程序需要对其进行操作的数据 。
( 2) 堆栈段用来在内存中建立一个适当的堆栈区,
以便在中断,子程序调用时使用 。 堆栈段一般可以从几十个字节至几千字节 。 如果太小,则可能导致程序执行中的堆栈溢出错误 。
( 3) 代码段包括了许多以符号表示的指令,其内容就是程序要执行的指令 。
3.3.3 汇编语言常用伪指令通常所说的机器指令是给 CPU的命令,在运行时由 CPU执行,每条指令对应 CPU的一种特定的操作,例如传送,加法,减法等;
而伪指令是给汇编程序的命令,在汇编过程中由汇编程序进行处理 。 例如定义数据,分配存储区,定义段及定义过程等 。 汇编以后,每条 CPU指令产生一一对应的目标代码;而伪指令则不产生与之相应的目标代码 。
宏汇编程序 MASM提供了约几十种伪指令,根据伪指令的功能,
大致可以分为以下几类:数据定义,符号定义,段定义,过程定义,宏处理,模块定义与连接,处理器方式,条件,列表,其它伪指令等 。
1,数据定义伪指令数据定义伪指令用来定义一个变量的类型,并将所需要的数据放入指定的存储单元中,可以只给变量分配存储单元,
而不赋予特定的值 。
数据定义伪指令的一般格式为:
[变量名 ] 伪指令 操作数 [,操作数 … ][;注释 ]
方括号中的变量名为任选项,它代表所定义的第一个单元的地址 。 变量名后面不要跟冒号,,,。 伪指令后面的操作数可以不止一个,如果有多个操作数时,相互之间应该用逗号,,,分开 。 注释项也是任选的 。
定义字节变量伪指令 DB
定义字变量伪指令 DW
定义双字变量伪指令 DD
定义四字变量伪指令 DQ
定义十字节变量伪指令 DT
数据定义伪指令后面的操作数可以是常数,表达式或字符串,但每项操作数的值不能超过由伪指令所定义的数据类型限定的范围 。 例如,DB伪指令定义数据的类型为字节,
则其范围应该是:无符号数,0~255;带符号数:- 128~
+ 127。
【 例 】 在给定的数据段中,分析数据定义伪指令的使用和存储单元的初始化 。
DATA SEGMENT ; 定义数据段
B1 DB 10H,30H ; 存入两个字节 10H,30H
B2 DB 2﹡ 3+5 ; 存入表达式的值 0BH
S1 DB 'GOOD! ' ; 存入 5个字符
W1 DW 1000H,2030H ; 存入两个字 1000H,2030H
W2 DD 12345678H ; 存入双字 1234H,5678H
S2 DB 'AB' ; 存入两个字符的 ASCII码 41H,42H
S3 DW 'AB' ; 存入 42H,41H
DATA ENDS ; 数据段结束
2,符号定义伪指令符号定义伪指令的用途是给一个符号重新命名,或定义新的类型属性等 。 这些符号可以包括汇编语言的变量名,标号名,过程名,寄存器名以及指令助记符等 。
常用的符号定义伪指令有 EQU,=,LABLE。
EQU伪指令:其作用是将表达式的值赋予一个名字,可以用这个名字来代替给定表达式 。
需要注意的是,一个符号一经 EQU伪指令赋值后,在整个程序中,不允许再对同一符号重新赋值 。
= ( 等号 ) 伪指令:其功能与 EQU伪指令基本相同,主要区别在于它可以对同一个名字重复定义 。
LABLE伪指令:其用途是在原来标号或变量的基础上定义一个类型不同的新的标号或变量 。
3,段定义伪指令段定义伪指令的用途是在汇编语言程序中定义逻辑段,用它来指定段的名称和范围,并指明段的定位类型,组合类型及类别 。
常用的段定义伪指令有:
SEGMENT/ENDS伪指令使用格式:段名 [定位类型 ] [组合类型 ] [’
类别 ’ ]
… ( 段内语句系列 )
段名 ENDS
4,过程定义伪指令在程序设计中,经常将一些重复出现的语句组定义为子程序,又称为过程,可以采用 CALL
指令来调用 。
使用格式:过程名 PROC [NEAR]/FAR
… ( 语句系列 )
RET
… ( 语句系列 )
过程名 ENDP
5,结构定义伪指令
( 1) 结构的定义:用伪指令 STRUC和 ENDS把相关数据定义语句组合起来,便构成一个完整的结构 。
使用格式:结构名 STRUC
… ( 数据定义语句序列 )
结构名 ENDS
( 2) 结构的预置:
结构变量名 结构名 ( 字段值表 )
( 3) 结构的引用:
结构变量名 ·结构字段名
6,模块定义与连接伪指令在编写规模较大的汇编语言源程序时,可以将整个程序划分为几个独立的源程序,称之为模块,然后将各模块分别进行汇编,生成各自的目标程序,
最后将它们连接成为一个完整的可执行程序 。 为了进行模块之间连接和实现相互的符号访问,以便进行变量传送,通常使用以下几个伪指令 。
NAME伪指令
END伪指令
PUBLIC伪指令
EXTRN伪指令
3.3.4 汇编语言程序上机过程一般情况下,在计算机上运行汇编语言程序的步骤如下:
1.用编辑程序 ( 例如 EDIT.COM) 建立扩展名为,ASM的汇编语言源程序文件;
2.用汇编程序 ( 例如 MASM.EXE) 将汇编语言源程序文件汇编成用机器码表示的目标程序文件,其扩展名为,OBJ;
3.如果在汇编过程中出现语法错误,根据错误的信息提示 (
如错误位置,错误类型,错误说明 ),用编辑软件重新调入源 程 序 进 行 修 改 。 没 有 错 误 时 采 用 连 接 程 序 ( 例如
LINK.EXE) 把目标文件转化成可执行文件,其扩展名为
.EXE;
4.生成可执行文件后,在 DOS命令状态下直接键入文件名就可执行该文件。
3.4 汇编语言程序设计
3.4.1 程序设计的基本步骤及程序基本结构
1,程序设计的基本步骤
( 1) 分析问题,抽象出数学模型
( 2) 确定算法或解题思想
( 3) 绘制流程图
( 4) 存储空间和工作单元初始化
( 5) 程序编制
( 6) 静态检查
( 7) 动态调试
2,程序的基本结构程序一般可以由顺序结构,分支结构和循环结构这 3
种组合而成 。 每一个结构只有一个入口和一个出口,
3种结构的任意组合和嵌套就构成了结构化的程序 。
( 1) 顺序结构:是按照语句的先后次序执行一系列的顺序操作
( 2) 分支结构:也叫条件选择结构,根据不同情况做出判断和选择,以便执行不同的程序段,分为双分支结构和多分支结构 。
( 3)循环结构:循环实际上是分支结构的一种扩展
,循环是否继续是依靠条件判断语句来完成的。按照条件判断的位置,可以把循环分为“当型循环”和“
直到型循环”。
3.4.2 顺序结构程序设计顺序结构程序从执行开始到最后一条指令为止
,指令指针 IP中的内容呈线性增加;从流程图上看
,顺序结构的程序只有一个起始框,一至几个执行框和一个终止框 。 在进行顺序结构程序设计时,主要考虑的是如何选择简单有效的算法,如何选择存储单元和工作单元 。
【 例 3.17】 试计算 S= ( W- ( X× Y+ Z- 340))
/X,设 W,X,Y,Z均为 16位带符号数 。 要求计算完成后,商和余数存入 S开始的字单元中 。
完整的汇编语言源程序如下:
DATA SEGMENT ; 数据段
W DW -245
X DW 15
Y DW -32
Z DW 280
RESULT DW 2 DUP(?)
DATA ENDS
CODE SEGMENT ; 代码段
ASSUME CS:CODE,DS:DATA
START,MOV AX,DATA ; 初始化 DS
MOV DS,AX
MOV AX,X ; 被乘数 X取出存入 AX中
IMUL Y ; X× Y
MOV CX,AX ; 乘积的低位字转存至 CX
MOV BX,DX ; 乘积的高位字转存至 BX
MOV AX,Z ; 加数 Z取出存入 AX中
CWD ; 将 Z扩展成双字
ADD CX,AX ; X× Y的低位字与 Z的低位字相加
ADC BX,DX ; X× Y的高位字与 Z的高位字及进位相加
SUB BX,340 ; X× Y+ Z的代位字减 340
SBB BX,0 ; X× Y+ Z的高位字减低位的借位
MOV AX,W ; W取出存入 AX
CWD ; 使 W扩展成双字
SUB AX,CX ;( W-( X× Y+ Z) -340) 低位运算
SBB DX,BX ;( W-( X× Y+ Z) -340) 高位运算
IDIV X ;( W-( X× Y+ Z) -340) /X
MOV RESULT,AX ; 商存入 RESULT单元
MOV RESULT+ 2,DX ; 余数目字存入 RESULT+ 2单元
MOV AH,4CH
INT 21H ; 返回 DOS
CODE ENDS
END START ; 汇编结束
3.4.3 分支结构程序设计分支程序的结构可以有两种形式:双分支结构和多分支结构 。 双分支程序是组成其它复杂程序的基本结构 。 首先要明确需要判断的条件;要用哪一个条件转移语句;条件成立的分支要完成什么任务
,条件不成立的分支要完成哪一些操作 。 多分支程序适用于有多种条件的情况 。
题目分析:根据数学中绝对值的概念知道,一个正数的绝对值是它本身,而一个负数的绝对值是它的相反数;要计算一个数的相反数
,需要完成减法运算,即用 0减去这个数。 8086指令系统中有专门的求相反数的指令 NEG。
【例 3.19】已知在内存中有一个字节单元 NUM,存有带符号数据,要求计算出它的绝对值后,放入 RESULT单元中。
源程序设计如下:
DATA SEGMENT
X DB -25
RESULT DB?
DATA ENDS
CODE SEGMENT
ASSUME DS,DATA,CS,CODE
START:MOV AX,DATA
MOV DS,AX ; 初始化
MOV AL,X ; X取到 AL中
TEST AL,80H ; 测试 AL正负
JZ NEXT ; 为正,转 NEXT
NEG AL ; 否则 AL求补
NEXT,MOV RESULT,AL ; 送结果
MOV AH,4CH
INT 21H ; 返回 DOS
CODE ENDS
END START ; 汇编结束
3.4.4 循环结构程序设计循环结构程序是经常用到的,主要由以下 4个部分组成:
( 1) 初始化部分
( 2) 循环体
( 3) 参数修改部分
( 4) 循环控制部分
【 例 3.22】 利用程序完成求 1~100的累加和,结果送到 RESULT单元中 。
采用递增计数法来实现求累加和,程序段如下:
DATA SEGMENT
RESULT DW?
CN EQU 100
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:MOV AX,DATA
MOV DS,AX ; 初始化
MOV AX,0
MOV CX,1 ; 循环初始化
LP,ADD AX,CX ; 求累加和
INC CX ; 计数器加 1
CMP CX,CN ; CX和计数终止值比较
JBE LP ; 小于等于终止值,转循环入口处 LP
MOV RESULT,AX ; 送结果
MOV AH,4CH
INT 21H ; 程序结束
CODE ENDS
END START ; 汇编结束循环程序可以有多重循环,又称为循环嵌套 。 在使用多重循环时要特别注意以下几点:
( 1) 内循环应完整地包含在外循环内,内外循环不能相互交叉 。
( 2) 内循环在外循环中的位置可根据需要任意设置,在分析程序流程时要避免出现混乱 。
( 3) 内循环既可以嵌套在外循环中,也可以几个循环并列存在 。 可以从内循环直接跳到外循环,但不能从外循环直接跳到内循环 。
( 4) 防止出现死循环,无论是内循环还是外循环,不要使循环回到初始化部分,否则将出现死循环 。
( 5) 每次完成外循环再次进入内循环时,初始条件必须重新设置 。
3.4.5 子程序设计在程序设计中,常把多处用到的同一个程序段或者具有一定功能的程序段单独存放在某一存储区域中,需要执行的时候
,使用调用指令转到这段程序来执行,执行完再返回原来的程序,这个程序段就称为子程序 。
调用子程序的程序段称为主程序 。 主程序中调用指令的下一条指令的地址称为返回地址,有时也称为断点 。
【 例 3.25】 设计一个子程序,完成统计一组字数据中的正数和 0的个数 。
DATA SEGMENT
ARR DW -123,456,67,0,-34,-90,89,67,0,256
CN EQU ($-ARR)/2
ZER DW?
PLUS DW?
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE
START:MOV AX,DATA
MOV DS,AX ; 初始化
MOV SI,OFFSET ARR ; 数组首地址送 SI
MOV CX,CN ; 数组元素个数送 CX
CALL PZN ; 调用近过程 PZN
MOV ZER,BX ; 0的个数送 BX
MOV PLUS,AX ; 正数的个数送 PLUS
MOV AH,4CH
INT 21H ; 返回 DOS; 子程序名,PZN; 子程序功能:统计一组字数据中的正数和 0的个数;入口参数:数组首址在 SI中,数组个数在 CX中;出口参数:正数个数在 AX中,0的个数在 BX中;使用寄存器,AX,BX,CX,DX,SI及 PSW
PZN PROC NEAR
PUSH SI
PUSH DX
PUSH CX ; 保护现场
XOR AX,AX
XOR BX,BX ; 计数单元清 0
PZN0,MOV DX,[SI] ; 取一个数组元素送 DX
CMP DX,0 ; DX中内容和 0比较
JL PZN1 ; 小于 0转 PZN1
JZ ZN ; 等于 0转 ZN
INC AX ; 否则为正数,AX中内容加 1
JMP PZN1 ; 转 PZN1
ZN,INC BX ; 为 0,BX中内容加 1
PZN1,ADD SI,2 ; 数组指针加 2调整
LOOP PZN0 ; 循环控制
POP CX
POP DX
POP SI ; 恢复现场
RET ; 返回主程序
PZN ENDP ; 子程序定义结束
CODE ENDS ; 代码段结束
END START ; 汇编结束
3.5 DOS和 BIOS中断调用
3.5.1 DOS功能调用
DOS功能调用可完成对文件,设备,内存的管理 。
1,系统功能调用的方法
( 1) 将入口参数送到指定寄存器中;
( 2) 子程序功能号送入 AH寄存器中;
( 3) 使用 INT 21H指令转入子程序入口执行相应操作 。
2,常用的几种系统功能调用
( 1) AH= 01H; 带显示的键盘输入
( 2) AH= 02H; 从显示器上输出单个字符
( 3) AH= 09H; 在显示器上输出字符串
( 4) AH= 0AH; 字符串输入到缓冲区
3.5.3 BIOS中断调用
IBM PC系列微机在只读存储器中提供了 BIOS基本输入输出系统,它占用系统板上 8K字节的 ROM区,又称为 ROM
BIOS。
BIOS为用户程序和系统程序提供主要外设的控制功能,如系统加电自检、引导装入及对键盘、磁盘、磁带、显示器
、打印机、异步串行通信口等的控制。计算机系统软件就是利用这些基本的设备驱动程序,完成各种功能操作。每个功能模块的入口地址都在中断矢量表中,通过中断指令
INT n可以直接调用。 n是中断类型号,每个类型号 n对应一种 I/ O设备的中断调用,每个中断调用又以功能号来区分其控制功能。
本章小结
8086CPU指令分为隐含操作数指令,单操作数指令和双操作数指令 3种 。 寻找操作数地址的方式称为寻址方式,8086有立即数寻址,寄存器寻址,直接寻址,寄存器间接寻址,相对寻址,基址变址寻址等 6种基本寻址方式 。
指令系统是程序设计的基础,8086CPU的指令系统按功能分为数据传送类,算术运算类,逻辑运算 ( 位操作 ) 类,串操作类,控制转移类,处理器控制类等 6
类指令 。
要熟悉汇编语言源程序的基本格式,正确运用语句格式来书写程序段,掌握伪指令的功能和应用,并通过上机操作,熟悉编辑程序,汇编程序,连接程序和调试程序等软件工具的使用,掌握源程序的建立,汇编,连接,运行,调试等技能 。
本章还介绍了汇编语言程序设计的一般步骤和方法,
熟悉各种程序的结构和编程技巧对汇编语言程序设计有着积极的促进作用 。
THANK YOU VERY MUCH
本章到此结束,
谢谢您的光临!