【任务】编制一个菜单程序,在屏幕上显示如下信息:
MENU
1. FILE
2. EDIT
3. COMPILE
4. RUN
0. QUIT
please choose one of 0~4:
选择1-4时,执行相应功能(简单起见,输出一句话即可),选择0时,退出程序。
【参考解答1】
assume cs:code, ss:stack
stack segment
db 100H dup (?)
stack ends
code segment
org 100h
start:
jmp beg
menu db 10,13,10,13,' MENU '
db 10,13
db 10,13,' 1. FILE'
db 10,13,' 2. EDIT'
db 10,13,' 3. COMPILE'
db 10,13,' 4. RUN'
db 10,13,' 0. QUIT'
db 10,13
db 10,13,' please choose one of 0~4:','$'
beg:
push cs
pop ds ;设置数据段
disp0:
lea dx,menu ;DS:DX=待输出字符的地址
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
mov ah,1
int 21h ;调用21h中断的第1号功能,从键盘读入字符,AL保存读入字符的ASCII码
cmp al,'0'
je exit
cmp al,'1'
je disp1
cmp al,'2'
je disp2
cmp al,'3'
je disp3
cmp al,'4'
je disp4
jmp disp0
disp1:
call sub1
jmp disp0
disp2:
call sub2
jmp disp0
disp3:
call sub3
jmp disp0
disp4:
call sub4
jmp disp0
exit:
mov ah,4ch
int 21h
sub1 proc near
jmp sub1_disp
file db 10,13,' --new, open, save, print files.---','$',10,13
sub1_disp:
lea dx,file
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub1 endp
sub2 proc near
jmp sub2_disp
edit db 10,13,' --copy, cut, paste the text.---','$',10,13
sub2_disp:
lea dx,edit
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub2 endp
sub3 proc near
jmp sub3_disp
compile db 10,13,' --compile the source file, then get target file.---','$',10,13
sub3_disp:
lea dx,compile
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub3 endp
sub4 proc near
jmp sub4_disp
run db 10,13,' --run, run, run, cannot stop.---','$',10,13
sub4_disp:
lea dx,run
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub4 endp
code ends
end start
【参考解答2】使用代码的直接定址表,简单且易扩充
assume cs:code, ss:stack
stack segment
db 100H dup (?)
stack ends
code segment
org 100h
start:
jmp beg
menu db 10,13,10,13,' MENU '
db 10,13
db 10,13,' 1. FILE'
db 10,13,' 2. EDIT'
db 10,13,' 3. COMPILE'
db 10,13,' 4. RUN'
db 10,13,' 0. QUIT'
db 10,13
db 10,13,' please choose one of 0~4:','$'
codetab dw sub1, sub2, sub3, sub4
beg:
push cs
pop ds ;设置数据段
disp0:
lea dx,menu ;DS:DX=待输出字符的地址
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
mov ah,1
int 21h ;调用21h中断的第1号功能,从键盘读入字符,AL保存读入字符的ASCII码
sub al, 30h ;ASCII变数字
cmp al, 0
je exit
mov bl, al
mov bh, 0
add bx, bx
sub bx, 2
call word ptr codetab[bx]
jmp disp0
exit:
mov ah,4ch
int 21h
sub1 proc near
jmp sub1_disp
file db 10,13,' --new, open, save, print files.---','$',10,13
sub1_disp:
lea dx,file
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub1 endp
sub2 proc near
jmp sub2_disp
edit db 10,13,' --copy, cut, paste the text.---','$',10,13
sub2_disp:
lea dx,edit
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub2 endp
sub3 proc near
jmp sub3_disp
compile db 10,13,' --compile the source file, then get target file.---','$',10,13
sub3_disp:
lea dx,compile
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub3 endp
sub4 proc near
jmp sub4_disp
run db 10,13,' --run, run, run, cannot stop.---','$',10,13
sub4_disp:
lea dx,run
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
ret
sub4 endp
code ends
end start
【参考解答3】用数据的直接定址表的解法,不过,这种解法只适合选择菜单后简单提示一句话的情形,各选项功能不一样时,还是解答2更具有普遍意义。
assume cs:code, ss:stack
stack segment
db 100H dup (?)
stack ends
code segment
org 100h
start:
jmp beg
menu db 10,13,10,13,' MENU '
db 10,13
db 10,13,' 1. FILE'
db 10,13,' 2. EDIT'
db 10,13,' 3. COMPILE'
db 10,13,' 4. RUN'
db 10,13,' 0. QUIT'
db 10,13
db 10,13,' please choose one of 0~4:','$'
file db 10,13,' --new, open, save, print files.---',10,13,'$'
edit db 10,13,' --copy, cut, paste the text.---',10,13,'$'
compile db 10,13,' --compile the source file, then get target file.---',10,13,'$'
run db 10,13,' --run, run, run, cannot stop.---',10,13,'$'
showtab dw file, edit, compile, run
beg:
push cs
pop ds ;设置数据段
disp0:
lea dx,menu ;DS:DX=待输出字符的地址
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
mov ah,1
int 21h ;调用21h中断的第1号功能,从键盘读入字符,AL保存读入字符的ASCII码
sub al, 30h ;ASCII变数字
cmp al, 0
je exit
mov bl, al
mov bh, 0
add bx, bx
sub bx, 2
mov dx,word ptr showtab[bx] ;用直接定址表取得要显示字符串的地址
mov ah,9
int 21h ;调用21h中断的第9号功能,显示以'$'结束的字符串
jmp disp0
exit:
mov ah,4ch
int 21h
code ends
end start