8086汇编用地址表法实现分支结构
(2011-10-17 22:13:43)
标签:
8086汇编地址表法分支结构校园 |
分类: 汇编 |
地址表,顾名思义就是用于存放地址的表。在汇编中,自定义标识符(标号)可以作为地址。数据标号,相当于变量名,用来标识存储在寄存器中的数据;语句标号,用来标识不同的语句段,在分支结构中经常使用。
地址表法,全称为地址常数表法,就是把多个分支中的每个分支程序的起始地址顺序放在一个存储区,这个存储区称为地址表存储区。这是书上的定义。我觉得:只要表中放的内容是地址,就可以看作是地址表。(所以才有了方法二)
下面通过一个例子来说明地址表法的使用方法。
例子:从键盘输入1——7个数字中的一个,让程序输出相应的星期几的英文,如输入4,则输出“Thursday”。
方法一:地址表中放的是各分支的语句标号。
输出结果为:
方法二:地址表中放的是数据标号。
地址表法,全称为地址常数表法,就是把多个分支中的每个分支程序的起始地址顺序放在一个存储区,这个存储区称为地址表存储区。这是书上的定义。我觉得:只要表中放的内容是地址,就可以看作是地址表。(所以才有了方法二)
下面通过一个例子来说明地址表法的使用方法。
例子:从键盘输入1——7个数字中的一个,让程序输出相应的星期几的英文,如输入4,则输出“Thursday”。
方法一:地址表中放的是各分支的语句标号。
DSEG SEGMENT
TAB DW
PROCA,PROCB, PROCC
DW
PROCD,PROCE,PROCF,PROCG
M DB 'Monday$'
TU DB 'Tuesday$'
W DB 'Wednesday$'
TH DB 'Thursday$'
F DB 'Friday$'
SA DB 'Saturday$'
SU DB 'Sunday$'
DSEG ENDS
CSEG SEGMENT
ASSUME DS:DSEG,CS:CSEG
START: MOV AX,DSEG
MOV DS,AX
MOV AH,1 ;输入数字字符
INT 21H
MOV BL,AL
MOV DL,0AH ;输出换行
MOV AH,2
INT 21H
MOV AL,BL
LEA BX,TAB
SUB AL,31H
CMP AL,0
JL START ;输入 0
CMP AL,6
JA START ;输入 > 7
SAL AL,1 ;扩大2倍
XOR AH,AH ;BYTE -->
WORD
ADD BX,AX
JMP [BX]
PROCA: LEA DX,M
JMP OVER
PROCB: LEA DX,TU
JMP OVER
PROCC: LEA DX,W
JMP OVER
PROCD: LEA DX,TH
JMP OVER
PROCE: LEA DX,F
JMP OVER
PROCF: LEA DX,SA
JMP OVER
PROCG: LEA DX,SU
OVER: MOV AH,9 ;输出结果
INT 21H
MOV AH,4CH ;返回操作系统
INT 21H
CSEG ENDS
END START
输出结果为:
E:\HB\HOME>A
<Enter>
1
Monday
E:\HB\HOME>A
<Enter>
7
Sunday
E:\HB\HOME>A
<Enter>
8
4
Thursday
E:\HB\HOME>A
<Enter>
0
6
Saturday
方法二:地址表中放的是数据标号。
DSEG SEGMENT
TAB DW
PROCA,PROCB,PROCC,PROCD,PROCE,PROCF,PROCG
;注意地址表中的标号应定义为WORD
PROCA DB 'Monday$'
PROCB DB 'Tuesday$'
PROCC DB 'Wednesday$'
PROCD DB 'Thursday$'
PROCE DB 'Friday$'
PROCF DB 'Saturday$'
PROCG DB 'Sunday$'
PROCH DB 'your input should between 1 and 7
.please input again:$'
DSEG ENDS
CSEG SEGMENT
ASSUME DS:DSEG,CS:CSEG
START: MOV AX,DSEG
MOV DS,AX
NEXT1: MOV AH,1 ;输入一个字符,其ASCII码放入AL中
INT 21H
MOV BL,AL
;将AL中的数据转存到BL中
MOV AH,1 ;控制输入回车,使输出时按了Enter键以后才输出结果的
INT 21H
MOV DL,10 ;输出换行
MOV AH,2
INT 21H
MOV AL,BL
LEA BX,TAB ;将地址表的偏移量存到BX中,待用
SUB AL,31H
JC NEXT2 ;输入0
CMP AL,7
JNC NEXT2 ;输入 >7
SAL AL,1 ;扩大2倍
XOR AH,AH ;扩充成字,为了和BX相加
ADD BX,AX
MOV
DX,[BX] ;将地址表的内容给DX,此内容实际上是各个数据标号的值,也是各个字符串的首地址
MOV AH,9 ;输出以DX为首地址的字符串
INT 21H
JMP OVER
NEXT2: LEA DX,PROCH ;获得提示语句的首地址
MOV AH,9 ;输出“错误提示”
INT 21H
JMP NEXT1
OVER: MOV AH,4CH ;返回操作系统
INT 21H
CSEG ENDS
END START
输出结果:
输出结果:
E:\HB\HOME>s
<Enter>
1 <Enter>
Monday
E:\HB\HOME>s
<Enter>
7 <Enter>
Sunday
E:\HB\HOME>s
<Enter>
0 <Enter>
your input should between 1 and 7 .please input again:8
<Enter>
your input should between 1 and 7 .please input again:9
<Enter>
your input should between 1 and 7 .please input again:4
<Enter>
Thursday
注意:方法一和方法二数据段、代码段的差异。
方法三:普通的多分支结构。(和地址表一点关系也没有)
注意:方法一和方法二数据段、代码段的差异。
方法三:普通的多分支结构。(和地址表一点关系也没有)
DSEG SEGMENT
M DB 'Monday$'
TU DB 'Tuesday$'
W DB 'Wedesday$'
TH DB 'Thursday$'
F DB 'Friday$'
SA DB 'Saturday$'
SU DB 'Sunday$'
E DB 'your input should between 1 and 7
.please input again:$'
DSEG ENDS
CSEG SEGMENT
ASSUME DS:DSEG,CS:CSEG
START: MOV AX,DSEG
MOV DS,AX
MOV AH,1
INT 21H
MOV BL,AL
MOV DL,0AH
MOV AH,2
INT 21H
MOV AL,BL
SUB AL,30H
CMP AL,1
JZ PROCA
CMP AL,2
JZ PROCB
CMP AL,3
JZ PROCC
CMP AL,4
JZ PROCD
CMP AL,5
JZ PROCE
CMP AL,6
JZ PROCF
CMP AL,7
JZ PROCG
JMP ERROR
PROCA: LEA DX,M
JMP OVER
PROCB: LEA DX,TU
JMP OVER
PROCC: LEA DX,W
JMP OVER
PROCD: LEA DX,TH
JMP OVER
PROCE: LEA DX,F
JMP OVER
PROCF: LEA DX,SA
JMP OVER
PROCG: LEA DX,SU
JMP OVER
ERROR: LEA DX,E
MOV AH,9
INT 21H
JMP START
OVER: MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CSEG ENDS
END START
显然,这种方法较方法一、方法二有些繁杂。
说明:
(1)美元符号“$”加载字符串的结尾主要起到截断数据的作用。如果没有“$”,将输出很多内容,包括许多乱码,因为它不仅输出了你定义的数据,而且输出了随机数据。
(2)标号要定义为WORD型,否则编译的时候会提示“Constant expected”错误。
(3)要注意输入格式和输出格式的控制。
(4)换行和回车的区别:换行是将光标移动到下一行开头,其ASCII码值为10(十六进制为0AH);回车是将光标移动到本行的开头,其ASCII值为13(十六进制为0DH).
(5)寄存器间接寻址只能用BX,SI,DI三个寄存器,而且要用中括号[]括起来。
(6)中括号[] 的作用不会体现在标号上,如下面的两个语句的作用是一样的:
DATA DW
1234H
语句一:MOVDX,DATA 或 MOV
DATA,DX
语句二:MOVDX,[DATA] 或 MOV
[DATA],DX
(7)注意输出语句会改变AL的值,容易忘记!
(8)输入、输出端口:
输入:默认输入字符的ASCII码值放在AL中
MOVAH,01H
INT21H
输出字符:默认输出字符的ASCII码值放在DL中
MOVAH,02H
INT21H
输出字符串:默认输出字符串的首地址放在DX中
MOVAH,09H
INT21H
返回操作系统:
MOVAH,4CH 或 MOV
AX,4C00H
INT21H
显然,这种方法较方法一、方法二有些繁杂。
说明:
(1)美元符号“$”加载字符串的结尾主要起到截断数据的作用。如果没有“$”,将输出很多内容,包括许多乱码,因为它不仅输出了你定义的数据,而且输出了随机数据。
(2)标号要定义为WORD型,否则编译的时候会提示“Constant expected”错误。
(3)要注意输入格式和输出格式的控制。
(4)换行和回车的区别:换行是将光标移动到下一行开头,其ASCII码值为10(十六进制为0AH);回车是将光标移动到本行的开头,其ASCII值为13(十六进制为0DH).
(5)寄存器间接寻址只能用BX,SI,DI三个寄存器,而且要用中括号[]括起来。
(6)中括号[] 的作用不会体现在标号上,如下面的两个语句的作用是一样的:
语句一:MOV
语句二:MOV
(7)注意输出语句会改变AL的值,容易忘记!
(8)输入、输出端口:
输入:默认输入字符的ASCII码值放在AL中
MOV
INT
输出字符:默认输出字符的ASCII码值放在DL中
MOV
INT
输出字符串:默认输出字符串的首地址放在DX中
MOV
INT
返回操作系统:
MOV
INT
前一篇:编程经常要用的快捷键