菜单程序的代码注释并不多,在前面几篇文章中都讲到过,基本就是把前面的文章进行整合,代码如下:
data segment
;登入界面
login db '------------LOGIN------------$'
tip_password db ' Please input password:$'
Tpassword db '1234$'
asterisk db '*$'
get_in db ' successfully!$ '
tip_wrong db ' Password wrong!$'
;主界面菜单
welcome db '------------Welcome to the system!------------$'
option1 db '1----------add$'
option2 db '2----------subtract$'
option3 db '3----------multiply$'
option4 db '4----------divide$'
option5 db '5----------d_to_h$'
option6 db '6----------d_to_o$'
option7 db '7----------d_to_b$'
option8 db '8----------exit$'
;定义变量
option db 2,?,?
getpassword db ?,?,?,?
first_number dw 6,?,?,?,?,?,? ;第一个数
second_number dw 6,?,?,?,?,?,? ;第二个数
ten dw 10
one1 dw ? ;第一个数的交换数
two1 dw ? ;第二个数的交换数
three1 dw ?
octonary_number db 6 ;存放输入的转八进制的空间
db ?
db 6 dup(?)
;提示
option_select db 'Please input your select:$'
mess1 db 'Please input the first number:$'
mess2 db 'Please input the second number:$'
exit_system db 'you have exited the system!$'
add_result db 'the two numbers sum is:$'
sub_result db 'the subtraction of two numbers is:$'
mul_result db 'The multiplication of two numbers is:$'
div_result db 'The quotient of the two numbers is:$'
line db '--------$'
hexadecimal db 'The hexadecimal of the number is:$'
input_error db 'input error!'
octonary db 'The octonary of the number is:$'
binary db 'The binary of the number is:$'
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov dx,offset login ;------------LOGIN------------
call output_strings
call newline
mov dx,offset tip_password ;Please input password:
call output_strings
mov cl,4
mov si,offset Tpassword
mov dl,0
judge:
mov ax,[si]
mov bl,al
call input_without_show
push dx
mov dx,offset asterisk
call output_strings
pop dx
cmp al,bl
jz true
false:
inc si
inc bp
dec cl
cmp cl,0
jz compare
jmp judge
true:
inc dl
inc si
inc bp
dec cl
cmp cl,0
jz compare
jmp judge
compare:
cmp dl,4
jz getin
jmp get_out
getin:
call newline
mov dl,offset get_in
call output_strings
call newline
jmp main_menu
get_out:
call newline
mov dl,0
mov dl,offset tip_wrong
call output_strings
call newline
call out_system
main_menu:
mov dx,offset welcome ;------------welcome------------
call output_strings
call newline
mov dx,offset option1
call output_strings
call newline
mov dx,offset option2
call output_strings
call newline
mov dx,offset option3
call output_strings
call newline
mov dx,offset option4
call output_strings
call newline
mov dx,offset option5
call output_strings
call newline
mov dx,offset option6
call output_strings
call newline
mov dx,offset option7
call output_strings
call newline
mov dx,offset option8
call output_strings
call newline
select:
mov dx,offset option_select
call output_strings ;输出:"Please input your select:"
mov dx,offset option
call input_strings
call newline
mov si,offset option+2
mov al,[si]
cmp al,'1'
jz select1
cmp al,'2'
jz select2
cmp al,'3'
jz select3
cmp al,'4'
jz select4
cmp al,'5'
jz select5
cmp al,'6'
jz select6
cmp al,'7'
jz select7
cmp al,'8'
jz select8
select1: ;加法
call option_1
jmp main_menu
select2: ;减法
call option_2
jmp main_menu
select3: ;乘法
call option_3
jmp main_menu
select4: ;除法
call option_4
jmp main_menu
select5:
call option_5
jmp main_menu
select6:
call option_6
call newline
jmp main_menu
select7:
call option_7
call newline
jmp main_menu
select8:
call out_system
option_7 proc near ;十进制转二进制
mov dx,offset mess1
call output_strings
mov dx,offset first_number
call input_strings ;输入第一个数
mov si,offset first_number+2
mov cx,first_number+1
mov ch,0 ;高位清零
mov three1,0 ;数据清零
bston:
mov al,[si]
sub al,30h
mov ah,0
xchg three1,ax
mul ten
add three1,ax
inc si
loop bston
mov bx,three1
mov dx,offset binary
call output_strings ;显示字符串
mov cl,16
mov ch,0
tb:
rcl bx,1 ;书p57
jc out1 ;当cf为1时输出1
jmp out0
tb1:
loop tb ;循环16次
ret
out1:
mov dl,'1'
call output_string
jmp tb1
out0:
mov dl,'0'
call output_string
jmp tb1
option_7 endp
option_6 proc near ;十进制转八进制
mov dx,offset mess1
call output_strings
mov dx,offset first_number
call input_strings
call newline
mov si,offset first_number+2 ;存放实际输入第一个数的首地址,si:指针寄存器
mov cx,first_number+1 ;存放实际宽度
mov ch,0 ;高位清零
mov three1,0 ;数据清零
geto:
mov al,[si]
sub al,30h
mov ah,0
xchg three1,ax
mul ten
add three1,ax
inc si
loop geto
mov dx,offset octonary
call output_strings ;显示字符串
mov ax,0
mov ax,three1
mov cx,0
push_number:
mov bx,8
mov dx,0 ;每次除法需要先将dx清零,否则会影响结果
div bx
push dx
inc cx
cmp ax,0
jnz push_number
put_number:
pop dx
add dl,30h
call output_string
loop put_number
ret
option_6 endp
option_5 proc near
mov dx,offset mess1
call output_strings
CALL READ ;读入十进制数,结果在BX
mov dx,offset hexadecimal
call output_strings ;在下一行显示提示符"$"
CALL CONVERT ;进行转换并输出
call newline
ret ;跳转到程序结束
option_5 endp
READ PROC near ;读入函数READ
MOV BX,0
NEWCHAR:
MOV AH,1 ; INT 21H, AH=1表示从键盘带回显读入字符到AL中
INT 21H
XOR AH,AH
CMP AL,'0' ;如果输入‘0'-'9'之外的字符,则结束读入
JS EXIT
CMP AL,'9'
JA EXIT
SUB AL,'0' ;把字符转换为数字,比如'8'转换为数字8,保存在AL
XCHG BX,AX
MOV CX,0AH
MUL CX ;把之前输入的数乘以10,加上本次输入,保存到BX.
XCHG BX,AX
ADD BX,AX
JMP NEWCHAR ;结果在BX
EXIT:
RET
READ ENDP
CONVERT PROC near ;转换函数
MOV CH,04D
ROTATE:
MOV CL,04D
ROL BX,CL ;BX循环左移4个bit, 也就是把最高位的16进制数放到BL的末尾
MOV AL,BL
AND AL,0FH ;把4位数放到AL
ADD AL,30H ;转换为ASCII
CMP AL,'9'
JB PRINT ;字符为'9'之下,直接显示;这个条件好象不对啊,应该是JBE才对
ADD AL,07H ;'9'之上的,转换为'A'-'F'
PRINT:
MOV DL,AL ;显示字符
MOV AH,2
INT 21H
DEC CH
JNE ROTATE ;循环
RET
CONVERT ENDP
option_1 proc near
call string_to_number
mov dx,offset add_result
call output_strings
mov ax,one1
mov bx,two1
add ax,bx
mov cx,ax
call output_five_numbers
call newline
ret
option_1 endp
option_2 proc near
call string_to_number
mov dx,offset sub_result
call output_strings
mov ax,one1
mov bx,two1
sub ax,bx
mov cx,ax
call output_five_numbers
call newline
ret
option_2 endp
option_3 proc near
call string_to_number
mov dx,offset mul_result
call output_strings
mov ax,one1
mov bx,two1
mul bx
mov cx,ax
call output_five_numbers
call newline
ret
option_3 endp
option_4 proc near
call string_to_number
mov dx,offset div_result
call output_strings
mov ax,one1
mov bx,two1
mov dx,0 ;存余数
div bx
push dx
mov cx,ax
call output_five_numbers
mov dx,offset line
call output_strings
pop dx
mov cx,dx
call output_five_numbers
call newline
ret
option_4 endp
string_to_number proc near
mov dx,offset mess1 ;输出提示:"please input the first number:"
call output_strings
mov dx,offset first_number ;输入第一个数
call input_strings
mov si,offset first_number+2 ;存放实际输入第一个数的地址
mov cx,first_number+1 ;存放实际输入元素的个数
mov ch,0
mov one1,0 ;用作交换
string_to_number1:
mov al,[si]
sub al,30h
mov ah,0
xchg one1,ax
mul ten
add one1,ax
inc si
loop string_to_number1
call newline
mov dx,offset mess2 ;输出:"请输入第二个数:"
call output_strings
mov dx,offset second_number
call input_strings
mov si,offset second_number+2
mov cx,second_number+1
mov ch,0
mov two1,0
string_to_number2:
mov al,[si]
sub al,30h
mov ah,0
xchg two1,ax
mul ten
add two1,ax
inc si
loop string_to_number2
call newline
ret
string_to_number endp
output_five_numbers proc near ;输出五位数
mov bx,10000
cycle:
push bx
mov ax,cx
mov dx,0
div bx ;(dx,ax)/src,商->ax,余数->dx
mov cx,dx
mov dl,al
add dl,30h
call output_string
pop ax
mov dx,0
div ten
mov bx,ax
cmp bx,0
jnz cycle
ret
output_five_numbers endp
input_strings proc near
push ax
mov ah,0ch ;清空当前输入缓冲区
mov al,0ah
int 21h
pop ax
ret
input_strings endp
output_strings proc near ;输出字符串
push ax
mov ah,09h
int 21h
pop ax
ret
output_strings endp
output_string proc near ;输出单个字符
push ax
mov ah,02h
int 21h
pop ax
ret
output_string endp
newline proc near ;输出“换行”
push dx
push ax
mov dl,0ah
call output_string
pop ax
pop dx
ret
newline endp
input_without_show proc near ;输入字符串但不显示
mov ah,08h
int 21h
ret
input_without_show endp
clean_screen proc near ;清屏
push ax
mov ah,15
int 10h
mov ah,0
int 10h
pop ax
ret
clean_screen endp
out_system proc near
mov ah,4ch
int 21h
out_system endp
code ends
end start