第五章 循环与分支程序设计
description
Transcript of 第五章 循环与分支程序设计
1
第五章 循环与分支程序设计
§5.1 循环与转移指令 §5.2 循环程序设计 §5.3 分支程序设计
2
§5.1 循环与转移指令
一、循环控制指令二、转移指令
控制转移类指令通过改变 IP (和 CS )值,实现程序执行顺序的改变
3
一、循环控制指令 8086 指令系统的循环控制指令均为二字节指令
一字节为转移的相对位移量( 8 位带符号的二进制数) IP ← IP+ 相对位移量
EIP ← EIP+ 相对位移量 隐含使用 CX 作为循环计数器
程序中的某段需反复执行若干次时,用循环来实现
短转移
4
LOOP label
; CX←CX - 1 , CX≠0 ,循环到标号 label
一、循环控制指令
LOOPE/LOOPZ label
; CX←CX - 1 , CX≠0 且 ZF = 1 ,循环到标号 label
LOOPNE/NZ label
; CX←CX - 1 , CX≠0 且 ZF = 0 ,循环到标号 label
等于时循环
不等于时循环
5
一、循环控制指令(例)MOV CX,COUNT ;设置循环次数
MOV SI,OFFSET DATA_BYTE
XOR AX,AX ; BX 清 0 ,用于存放累加和
AGAIN: ADD AL,[SI]
ADC AH,0
INC SI
LOOP AGAIN ;计数器减 1 ,不为 0 继续循环
6
一、循环控制指令(例)MOV CX,COUNT ;设置循环次数
MOV SI,OFFSET STRING
XOR BX,BX ; BX 清 0 ,用于记录空格数
MOV AL,20H
AGAIN: CMP AL,[SI]
JNZ NEXT ; ZF=0 ,非空格,转移
INC BX ; ZF=1 ,是空格,个数加 1
NEXT: INC SI
LOOP AGAIN ;计数器减 1 ,不为 0 继续循环
7
二、转移指令
无条件转移指令 条件转移指令
8
无条件转移指令
JMP label
;程序转向 label 标号指定的地址
NEARFAR
只要执行无条件转移指令 JMP ,就使程序转到指定的目标地址处,从目标地址处开始执行那里的指令
JMP 指令分成 4 种类型:⑴ 段内转移、直接寻址⑵ 段内转移、间接寻址⑶ 段间转移、直接寻址⑷ 段间转移、间接寻址
目的地址与 JMP 属同一逻辑段,只修改 IP 值
从一个代码段转移到另一个代码段, CS和 IP 都会被修改
9
1. 无条件转移指令—目标地址的寻址方式
直接寻址方式 转移地址象立即数一样,直接在指令的机器代码中,就
是直接寻址方式 间接寻址方式
转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式
用标号表达
用寄存器或存储器操作数表达
10
1. 无条件转移指令—目标地址的范围:段内
段内转移——近转移( near ) 在当前代码段 64KB 范围内转移 ( ±3
2KB 范围) 不需要更改 CS 段基值,只要改变 IP 偏
移地址 段内转移——短转移( short )
转移范围可以用一个字节表达,在段内- 128 ~+ 127 范围的转移
代码
段
代码
段
11
1. 无条件转移指令—目标地址的范围:段间
段间转移——远转移( far ) 从当前代码段跳转到另一个代码段,可以
在 1MB 范围 需要更改 CS 段基值和 IP 偏移地址 目标地址必须用一个 32 位数表达,叫做
32 位远指针,它就是逻辑地址
代码
段
代码
段
实际编程时,汇编程序会根据目标地址的距离,自动处理成短转移、近转移或远转移程序员可用操作符 short 、 near ptr 或 far ptr 强制
12
段内直接寻址转移
JMP label ; IP←IP+ 位移量位移量是紧接着 JMP 指令后的那条指令的偏移地址,到目标指令的偏移地址的地址位移当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负
实际为相对寻址
JMP AGAIN ;转移到 AGAIN 处继续执行……AGAIN: DEC CX ;标号 AGAIN 的指令
……JMP OUTPUT ;转向 OUTPUT……
OUTPUT: MOV RESULT,AL ;标号 OUTPUT 的指令
13
段内间接寻址转移
JMP r16/m16 ; IP←r16/m16将一个 16 位寄存器或主存字单元内容送入 IP 寄存器,作为新的指令指针,但不修改 CS 寄存器的内容
JMP AX ; IP←AX
JMP WORD PTR [BX] ; IP←[BX]
14
段间直接寻址转移JMP far ptr label
; IP←label 的偏移地址; CS←label 的段基值
将标号所在段的段基值作为新的 CS 值,标号在该段内的偏移地址作为新的 IP 值;程序跳转到新的代码段执行
JMP FAR PTR OTHERSEG
;远转移到代码段 2 的 otherseg
15
段间间接寻址转移JMP far ptr mem
; IP←[mem] , CS←[mem+2]
用一个双字存储单元表示要跳转的目标地址。这个目标地址存放在主存中连续的两个字单元中的,低位字送 IP 寄存器,高位字送 CS 寄存器
MOV WORD PTR [BX],0
MOV WORD PTR [BX+2],1500H
JMP FAR PTR [BX] ;转移到 1500H:0
16
2. 条件转移指令
Jcc label
;条件满足,发生转移: IP←IP + 8 位位移量 ;条件不满足,顺序执行
指定的条件 cc 如果成立,程序转移到由标号 label 指定的目标地址去执行指令;条件不成立,则程序将顺序执行下一条指令
操作数 label 是采用短转移,称为相对寻址方式
17
2. 条件转移指令 Jcc 指令的操作数 label 是一个标号
一个 8 位位移量是相对于当前 IP 的,且距当前 IP 地址-128 ~+ 127 个单元的范围之内,属于段内短距离转移
Jcc 指令为 2 个字节,条件不满足时的顺序执行就是当前指令偏移指针 IP 加 2
18
2. 条件转移指令—指令的分类 Jcc 指令不影响标志,但要利用标志。
根据利用的标志位不同, 19 条指令分成 4 种情况:⑴ 判断单个标志位状态⑵ 比较无符号数高低⑶ 比较有符号数大小⑷ 判断计数器 CX 为 0
19
助记符 标志位 助记符 标志位
JC CF=1 JA/JNBE CF=0 且 ZF=0
JNC CF=0 JAE/JNB CF=0 或 ZF=1
JZ/JE ZF =1 JB/JNAE CF=1 且 ZF=0
JNZ/JNE ZF =0 JBE/JNA CF=1 或 ZF=1
JS SF =1 JG/JNLE SF=OF 且 ZF=0
JNS SF=0 JGE/JNL SF=OF 或 ZF=1
JP/JPE PF =1 JL/JNGE SF≠ OF 且 ZF=0
JNP/JPO PF =0 JLE/JNG SF≠ OF 或 ZF=1
JO OF =1 JCXZ CX=0
JNO OF =0
实际虽然指令只有 19 条,但却有 31 个助记符
采用多个助记符,只是为了方便记忆和使用
20
判断单个标志位状态这组指令单独判断 5 个状态标志之一
⑴JZ/JE 和 JNZ/JNE :利用零标志 ZF ,判断结果是否为零(或相等)
⑵JS 和 JNS :利用符号标志 SF ,判断结果是正是负
⑶JO 和 JNO :利用溢出标志 OF ,判断结果是否产生溢出
⑷JP/JPE 和 JNP/JPO :利用奇偶标志 PF ,判断结果中“ 1”的个数是偶是奇
⑸JC 和 JNC :利用进位标志 CF ,判断结果是否进位或借位
例 题例 题
例 题例 题
例 题例 题
例 题例 题
例 题 例 题
21
2. 条件转移指令— JZ/JNZ 指令REPZ CMPSB ;重复比较两个字符JNZ UNMAT ; ZF = 0 (不等),转移MOV AL,0 ;顺序执行(相等)JMP OUTPUT
UNMAT: MOV AL,0FFH OUTPUT: MOV RESULT,AL
REPZ CMPSB ;重复比较两个字符JZ MAT ; ZF = 1 (相等),转移MOV AL,0FFH ;顺序执行(不等)JMP OUTPUT
MAT: MOV AL,0 OUTPUT: MOV RESULT,AL
22
2. 条件转移指令— JS/JNS 指令 计算 |X - Y| (绝对值)。 X 和 Y 为存放于 X 单元和 Y 单
元的 16 位操作数,结果存入 RESULT 。
MOV AX,XSUB AX,YJNS NONNEGNEG AX
NONNEG: MOV RESULT,AX
23
2. 条件转移指令— JO/JNO 指令 计算 X - Y 。 X 和 Y 为存放于 X 单元和 Y 单元的 16 位操
作数,若溢出,则转移到 OVERFLOW 处理
MOV AX,XSUB AX,YJO OVERFLOW... ;无溢出,结果正确
OVERFLOW: ... ;有溢出处理
24
2. 条件转移指令— JP/JNP 指令 设字符的 ASCII 码在 AL 寄存器中。将字符加上奇校验位:
在字符 ASCII 码中为“ 1”的个数为奇数时令其最高位为“0”,否则令最高位为“ 1”
AND AL,7FH ;最高位置“ 0”,同时判断“ 1”的个数
JNP NEXT ;个数已为奇数,则转向 NEXT
OR AL,80H ;否则,最高位置“ 1”
NEXT: ...
25
2. 条件转移指令— JC/JNC 指令 记录 BX 中 1 的个数
XOR AL,AL ; AL = 0 , CF = 0
AGAIN: TEST BX,0FFFFH ;等价于 CMP BX,0
JZ NEXT
SHL BX,1
JNC AGAIN
INC AL
JMP AGAIN
NEXT: ... ; AL保存 1 的个数
26
2. 条件转移指令—无符号数的比较
无符号数的大小用高( Above )低( Below )表示利用 CF确定高低、利用 ZF 标志确定相等( Equal )两数的高低分成 4 种关系:
⑴ 高于(不低于等于): JA ( JNBE )
⑵ 高于等于(不低于): JAE ( JNB )
⑶ 低于(不高于等于): JB ( JNAE )
⑷ 低于等于(不高于): JBE ( JNA )
27
2. 条件转移指令—无符号数的比较(例)
CMP AX,BX ;比较 AX 和 BX
JAE NEXT ;若 AX≥BX ,转移
XCHG AX,BX ;若 AX < BX ,交换
NEXT: ...
结果: AX保存较大的无符号数
28
2. 条件转移指令—有符号数的比较
有符号数的大( Greater )小( Less )需要组合OF 、 SF 标志,并利用 ZF 标志确定相等( Equal )
两数的大小分成 4 种关系: ⑴ 小于(不大于等于): JL ( JNGE ) ⑵ 小于等于(不大于): JLE ( JNG ) ⑶ 大于(不小于等于): JG ( JNLE ) ⑷ 大于等于(不小于): JGE ( JNL )
29
2. 条件转移指令—有符号数的比较(例)
CMP AX,BX ;比较 AX 和 BX
JGE NEXT ;若 AX≥BX ,转移
XCHG AX,BX ;若 AX < BX ,交换
NEXT: ...
结果: AX保存较大的有符号数
30
2. 条件转移指令—计数器 CX 为 0 转移
JCXZ label
; CX = 0 ,发生转移: IP←IP + 8 位位移量 ; CX≠0 ,顺序执行
CX 寄存器通常在程序中用做计数器JCXZ 指令用来判断计数是否为 0
31
§5.2 循环程序设计
一、循环程序的结构形式二、循环程序设计三、多重循环程序设计
32
一、循环程序的结构形式
结束
初始化
循环的初始状态
循环体
循环的工作部分及修改部分
计数控制循环条件控制循环
修改部分
控制条件Y
N先循环,后判断
33
一、循环程序的结构形式
结束
初始化
循环的初始状态
循环体
循环的工作部分及修改部分
计数控制循环条件控制循环
修改部分
控制条件
Y
N
先判断,后循环
34
xor ax,ax ;被加数 ax 清 0mov cx,100
again: add ax,cx ;从 100,99,...,2,1倒序累加loop again
.model small
.stack 256
.datasum dw ?
.code
.startup
mov sum,ax ;将累加和送入指定单元
.exit 0end
二、循环程序设计(例)
35
例 5.2 在 ADDR 单元存放着数 Y的地址,试编制一程序把Y 中 1的个数存入 COUNT 单元中
开始
1 的个数计数器← 0
循环次数计数器 CX←16
Y 左移一次
CF=1
1 的个数计数器 +1
CX ←CX-1=0
COUNT ← 1 的个数计数器
结束
N
Y
N
Y
循环次数固定,完全由循环计数器控制
36
DATA SEGMENT
Y DW 1234H
ADDR DW Y
COUNT DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DL,0
MOV BX,ADDR
MOV AX,[BX]
MOV CX,16
REPEAT:
SHL AX,1 JNC NEXT INC DL
NEXT: LOOP REPEATEXIT0: MOV COUNT,DL
MOV AH,4CH INT 21H
CODE ENDS END START
例 5.2
37
开始
1 的个数计数器← 0
循环次数计数器 CX←16
Y 左移一次
CF=1
1 的个数计数器 +1
CX ←CX-1=0
COUNT ← 1 的个数计数器
结束
NY
N
Y
Y=0
N
Y
例 5.2
38
DATA SEGMENT
Y DW 1234H
ADDR DW Y
COUNT DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DL,0
MOV BX,ADDR
MOV AX,[BX]
MOV CX,16
REPEAT:
SHL AX,1
JNC NEXT
INC DL
NEXT: LOOP REPEAT
EXIT0: MOV COUNT,DL
ADD DL,30H
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
CMP AX,0
JZ EXIT0
例 5.2
JMP REPEAT
39
例 5.4 将正数 N 插入一个已升序排列的字数组的正确位置。该数组的首地址和末地址分别为 ARRAY_ HEAD 和 ARRAY_ END ,其中所有的数均为正数。
解法一: 从数组的尾部开始比较 N较大,则在比较对象后插入,结束循环
N较小,则把比较对象及其后元素后移一个字
循环结束的控制: 执行插入操作后结束循环
若 N比所有元素都小,扫描整个数组后仍无法结束循环,将 -1 加在数组前可解决该问题
23, 37, 49, 52
32
ENDHEAD
-1, 23, 37, 49, 5232,-1,
40
开始
(ARRAY_HEAD-2)←-1
初始化变址寄存器 SI
将 N放在 K的后面
K<=N
修改地址
K后移一个字单元
结束
Y
N
例 5.4
41
DATAREA SEGMENT
X DW ?
ARRAY_HEAD DW 3,5,15,23,37,49
ARRAY_END DW 105
N DW 32
DATAREA ENDS
PROGRAM SEGMENT
MAIN PROC FAR
ASSUME CS:PROGRAM,DS:DATAREA
START: PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATAREA
MOV DS,AX
MOV AX,N
MOV ARRAY_HEAD-2,-1
MOV SI,0
COMP:CMP ARRAY_END[SI],AX
JLE INSERT
MOV BX,ARRAY_END[SI]
MOV ARRAY_END[SI+2],BX
SUB SI,2
JMP COMP
INSERT:
MOV ARRAY_END[SI+2],AX
RET
MAIN ENDP
PROGRAM ENDS
END START
例 5.4
MOV BX,ARRAY_END[SI]
CMP BX,AX
JLE INSERT
42
例 5.4 将正数 N 插入一个已升序排列的字数组的正确位置。 该数组的首地址和末地址分别为 ARRAY_ HEAD 和ARRAY_ END ,其中所有的数均为正数。
解法二: 从数组的头部开始比较 N较小,则在比较对象前插入,结束循环
N较大,则把比较对象及其前元素前移一个字
循环结束的控制: 可扫描整个数组,循环次数为数组元素个数执行插入操作后结束循环
若 N比所有元素都小,形成新的头;若 N比所有元素都大,则被置于尾部
43
DSEG SEGMENT PARA 'DATA'
DW ?
ARRAY_HEAD DW 3,5,13H,23H,37H
DW 49H,52H,65H,78H,99H,105H
COUNT EQU ( $-ARRAY_HEAD ) /2
N DW 32H
DSEG ENDS
CSEG SEGMENT PARA 'CODE'
ASSUME CS:CSEG
ASSUME DS:DSEG,SS:SSEG
MAIN PROC FAR
;MAKE NECCESSARY
INITALIZALITION
MOV AX,DSEG
MOV DS,AX
MOV ES,AX
MOV AX,N
MOV SI,0
MOV CX,COUNT
REPEAT: MOV BX,ARRAY_HEAD[SI]
CMP BX,AX
JAE INSERT ;N 较小,则转插入操作
MOV ARRAY_HEAD[SI-2],BX
; 数组元素前移 1 字单元
INC SI
INC SI
LOOP REPEAT
INSERT: MOV ARRAY_HEAD[SI-2],AX
; 将 N加入到数组中
MOV AX,4C00H
INT 21H
MAIN ENDP
CSEG ENDS
END MAIN ;SET ENTRY POINT
44
例 5.5 设有数组 X 和 Y ,每个数组都有 10个元素,完成以下计算:
Z1=X1+Y1 Z2=X2+Y2 Z3=X3-Y3
Z4=X4-Y4 Z5=X5-Y5 Z6=X6+Y6
Z7=X7-Y7 Z8=X8-Y8 Z9=X9+Y9
Z10=X10+Y10
结果存入数组 Z 。
比例尺: 0000000011011100B
45
DATA SEGMENT
X DW 11,33,10,60,4,7,19,80,45,23
Y DW 44,5,2,90,78,32,12,10,100,98
Z DW 10H DUP(?)
FLAG DW 0000000011011100B
DATA ENDS
STK SEGMENT STACK
DW 20H DUP(0)
STK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STK
START:
MOV AX,DATA
MOV DS,AX
MOV BX,0
MOV CX,10
MOV DX,FLAG
NEXT: MOV AX,X[BX]
SHR DX ,1
JC SUBTRACT
ADD AX,Y[BX]
JMP RESULT
SUBTRACT :
SUB AX,Y[BX]
RESULT :
MOV Z[BX],AX
ADD BX,2
LOOP NEXT
MOV AH,4CH
INT 21H
CODE ENDS
END START
46
三、多重循环程序设计 例 5.7 有一个首地址为 A 的 N字数组,请编制程序
使该数组中的数按照从大到小的次序整序
冒泡法从第一个元素开始,依次对相邻的两个元素进行比较,使前一个元素不小于后一个元素;将所有元素比较完之后,最小的元素排到了最后;然后,除掉最后一个元素之外的元素依上述方法再进行比较,得到次小的元素排在后面;如此重复,直至完成就实现元素从大到小的排序
这需要一个双重循环程序结构
47
冒泡法的排序
序号 数
比 较 遍 数
1 2 3 4
1 32
2 15
3 16
4 8
5 85
32
16
15
85
8
32
16
85
15
8
32
85
16
15
8
85
32
16
15
8
48
CSEG SEGMENT PARA ‘CODE’ASSUME CS:CSEG, DS:DSEG,SS:SSEG
MAIN PROC FAR ;MAKE NECCESSARY INITALIZALITIONPUSH DSXOR AX,AXPUSH AXMOV AX,DSEGMOV DS,AXMOV ES,AXMOV CX,NDEC CX
LOOP1: MOV DI,CX ; 保存计数器MOV BX,0 ; 数组地址指针清零
LOOP2: MOV AX,A[BX]CMP AX,A[BX+2]JGE COTINUEXCHG A[BX+2],AX ; 交换MOV A[BX],AX
COTINUE:ADD BX,2 ; 修改数组指针LOOP LOOP2MOV CX,DI ; 恢复循环计数器LOOP LOOP1RET
MAIN ENDPCSEG ENDS
END MAIN ;SET ENTRY POINT
49
CSEG SEGMENT PARA ‘CODE’ASSUME CS:CSEG, DS:DSEG,SS:SSEG
MAIN PROC FAR ;MAKE NECCESSARY INITALIZALITIONPUSH DSXOR AX,AXPUSH AXMOV AX,DSEGMOV DS,AXMOV ES,AXMOV CX,NDEC CX
LOOP1: MOV DI,CX ; 保存计数器MOV BX,0 ;数组地址指针清零MOV DL,0
LOOP2: MOV AX,A[BX]CMP AX,A[BX+2]JGE COTINUEXCHG A[BX+2],AX ; 交换MOV A[BX],AXINC DL ; 交换次数计数器 +1
COTINUE:ADD BX,2 ;修改数组指针LOOP LOOP2CMP DL,0JZ EXIT0 ; 数组已整序,则退出MOV CX,DI ; 恢复循环计数器LOOP LOOP1
EXIT0: RET MAIN ENDP CSEG ENDS
END MAIN ;SET ENTRY POINT
50
§5.3 分支程序设计
一、分支程序的结构形式二、分支程序的设计三、跳转表
51
一、分支程序的结构形式
AH=0 fuction0N
AH=1
AH=2
fuction1
fuction2
N
N
Y
Y
Y
( C )多分支结构
52
分支程序的设计方法 例 5.9 在附加段中,有一个按从小到大顺序排列的无符号数
数组,其首地址存放在 DI 寄存器中,数组中的第一个单元存放着数组长度。在 AX 中有一无符号数,要求在数组中查找该数,如找到则使 CF=0 ,并在 SI 中给出该元素的偏移地址;如未找到,则使 CF=1 。
53
54
跳跃表法 例 5.10 试根据 AL 寄存器中哪一位为 1 (从低位到
高位)把程序转移到 8 个不同的程序分支去。 跳转目标的地址在数据段中( 5-10-1.asm) 跳转目标的地址在代码段中( 5-10-2.asm)
55
SSEG SEGMENT PARA STACK 'STACK'DW 100H DUP(0)
SSEG ENDSDSEG SEGMENT PARA 'DATA'TAB DW ROUTINE1 ;程序段 1 在代码段的偏移量
DW ROUTINE2DW ROUTINE3DW ROUTINE4DW ROUTINE5DW ROUTINE6DW ROUTINE7DW ROUTINE8
MESS DB 'THIS IS ROUTINE 'NUMBERDB 8
DB 0AH,0DH,'$'DSEG ENDSCSEG SEGMENT PARA 'CODE'
ASSUME CS:CSEG, DS:DSEG,SS:SSEGMAIN PROC FAR
MOV AX,DSEG ;MAKE NECCESSARY INITALIZALITION
MOV DS,AXMOV ES,AX
MOV AL, NUMBERCMP AL,0JE CONTINUE_MAIN_LINE;AL 值为 0 则继续运行主程序段LEA BX,TAB
LOP1: SHR AL,1JNC NOT_YETJMP WORD PTR [BX]
NOT_YET:ADD BX,TYPE TABJMP LOP1
CONTINUE_MAIN_LINE:MOV AH,4CHINT 21H
56
ROUTINE1:MOV NUMBER, 31HJMP EXIT
ROUTINE2:MOV NUMBER, 32HJMP EXIT
ROUTINE3:MOV NUMBER, 33HJMP EXIT
ROUTINE4:MOV NUMBER, 34HJMP EXIT
ROUTINE5:MOV NUMBER, 35HJMP EXIT
ROUTINE6:MOV NUMBER, 36HJMP EXIT
ROUTINE7:MOV NUMBER, 37HJMP EXIT
ROUTINE8:MOV NUMBER, 38HJMP EXIT
EXIT: MOV DX,OFFSET MESS
MOV AH,9
INT 21H
JMP CONTINUE_MAIN_LINE
;MOV AH,0AH
;INT 21H
;RETURN DOS
MOV AX,4C00H
INT 21H
MAIN ENDP
CSEG ENDS
END MAIN ;SET ENTRY POINT
57
SSEG SEGMENT PARA STACK 'STACK'DW 100H DUP(0)
SSEG ENDS
DSEG SEGMENT PARA 'DATA'MESG1: DB 'PLEASE INPUT THE NUMBER:$'MESS DB 0AH,0DH,'THIS IS ROUTINE 'NUMBER DB ?
DB 0AH,0DH,'$'DSEG ENDS
CSEG SEGMENT PARA 'CODE'ASSUME CS:CSEG, DS:DSEG,SS:SSEG
MAIN PROC FAR;MAKE NECCESSARY INITALIZALITIONMOV AX,DSEGMOV DS,AXMOV ES,AX
MOV DX,OFFSET MESG1MOV AH,9INT 21HMOV AH,1 ; 从键盘获得 AL 值INT 21HAND AL,0FHDEC AL ; 计算表地址 (号 -1)*3MOV BL,ALSHL BL,1ADD BL,ALMOV BH,0ADD BX,OFFSET TABJMP BX
TAB: JMP ROUTINE1JMP ROUTINE2JMP ROUTINE3JMP ROUTINE4JMP ROUTINE5JMP ROUTINE6JMP ROUTINE7JMP ROUTINE8JMP ROUTINE9
58
ROUTINE1:MOV NUMBER, 31HJMP EXIT
ROUTINE2:MOV NUMBER, 32HJMP EXIT
ROUTINE3:MOV NUMBER, 33HJMP EXIT
ROUTINE4:MOV NUMBER, 34HJMP EXIT
ROUTINE5:MOV NUMBER, 35HJMP EXIT
ROUTINE6:MOV NUMBER, 36HJMP EXIT
ROUTINE7:MOV NUMBER, 37HJMP EXIT
ROUTINE8:MOV NUMBER, 38HJMP EXIT
ROUTINE9:MOV NUMBER, 39HJMP EXIT
EXIT: MOV DX,OFFSET MESSMOV AH,9INT 21H;MOV AH,0AH;INT 21H
;RETURN DOSMOV AX,4C00HINT 21H
MAIN ENDPCSEG ENDS
END MAIN ;SET ENTRY POINT