📄 caa.asm
字号:
;############## calculator ########################
data segment
x dw 0,0
y dw 0,0
z dw 0,0,0,0
buf dw 0,0
result dw 0,0,0,0
outstring db 12 dup(0) ;output string
sign db 0
operator db 0
tag db ? ;label for repeat or not
flag db 0 ;if(flag==0) then '0' will not be outputed
kkk dw 0h,0h,0h,0h,0h,3e8h,0h,0h,586h,0h,0h,6c4h,0h,0h,7d0h,0h,0h,8bch,0h,0h,991h,0h,0h,0a56h,0h,0h,0b0ch,0h,0h,0bb8h
dcb dw 17h,4876h,0e800h, 2h,540bh,0e400h, 0,3b9ah,0ca00h,0,5f5h,0e100h,0,98h,9680h,0,0fh,4240h,0,1h,86a0h,0,0,2710h,0,0,3e8h,0,0,64h,0,0,0ah,0,0,1h
m1 db ' please input the first data(x): $'
m2 db ' please input the second data(y): $'
opr db ' please select the order 1)+ 2)- 3)* 4)/ 5)x^y 6)x(1--9)kpf: $'
err db ' input error!$ '
res db ' the result is: $'
cout db ' calculator',0dh,0ah,' $'
cout1 DB ' --------------------------------------------- ',0DH,0AH,'$'
cout2 db ' 1.jia (x+y)',0DH,0AH,'$'
cout3 db ' 2.jian (x-y)',0DH,0AH,'$'
cout4 db ' 3.sheng(x*y) ',0DH,0AH,'$'
cout5 db ' 4.chu (x/y)',0DH,0AH,'$'
cout6 db ' 5.x^y ',0DH,0AH,'$'
cout7 db ' 6.2_|-x (0--9)',0DH,0AH,'$'
cout8 DB ' --------------------------------------------- ',0DH,0AH,'$'
again db ' would you like to continue (y/n)? $'
data ends
code segment
assume cs:code,ds:data
start:
main proc far
mov ax,data
mov ds,ax
mov ax,0600h ;ah=6,al=0,clear screen
mov cx,0000h;左上角:0,0
mov dx,184fh;右下角:18,4f
mov bh,07
int 10h
mov ah,02 ;定位光标位置
mov bh,0
mov dx,041fh
int 10h
lea dx,cout
mov ah,9h
int 21h
lea dx,cout1
mov ah,9h
int 21h
lea dx,cout2
mov ah,9h
int 21h
lea dx,cout3
mov ah,9h
int 21h
lea dx,cout4
mov ah,9h
int 21h
lea dx,cout5
mov ah,9h
int 21h
lea dx,cout6
mov ah,9h
int 21h
lea dx,cout7
mov ah,9h
int 21h
lea dx,cout8
mov ah,9h
int 21h
repeat:
mov bx,10
mov sign,0 ;sign of the result
mov tag,0
call input1
call input2
call select ;select operator
mov dl,13 ;next line
mov ah,02h
int 21h
mov dl,10
mov ah,02h
int 21h
mov al,operator
cmp al,1
jnZ l0
call a ;add
jmp l3
l0: cmp al,2
jnZ l1
call s ;subtract
jmp l3
l1: cmp al,3
jnZ l2
call m ;multiply
jmp l3
l2: cmp al,4
jnZ ll
call d ;divided by
ll: cmp al,5
jnZ lll
call kcf
lll: cmp al,6
jnZ l3
call kpf
l3: mov dl,13 ;next line
mov ah,02h
int 21h
mov dl,10
mov ah,02h
int 21h
call re ;ask if repeat
mov dl,13
mov ah,02h
int 21h
mov dl,10
mov ah,02h
int 21h
mov al,tag
cmp al,1
jz repeat
mov ah,4ch ;over
int 21h
main endp
;############### enter the first oprand ###################
input1 proc near
mov cx,6 ;for 6 bit of decimal most
mov x,0 ;let x=0 in case calculation is doing for more than once
mov x+2,0
lea dx,m1
mov ah,09h
int 21h
l4: mov ah,01h
int 21h
cmp al,0dh ;when receive 'enter' cease the input
jZ l5
sub al,30h ;if (al) < 0 , error
jc next1
cmp al,0ah
jnc next1 ;if (al) >10, error
mov ah,0
mov buf,ax
mov ax,x+2 ; x = x*10 + (al)
mul bx
mov x+2,ax
mov ax,x
mov dx,0
mul bx
add ax,buf
mov x,ax
adc x+2,dx
loop l4
jmp l5
next1: lea dx,err ;error
mov ah,09h
int 21h
l5: mov dl,13 ;next line
mov ah,02h
int 21h
mov dl,10
mov ah,02h
int 21h
ret
input1 endp
;################ enter the second operand #######################
input2 proc near
mov cx,6 ;for 6 bit of decimal most
mov y,0 ;let y=0 in case calculation is doing for more than once
mov y+2,0
lea dx,m2
mov ah,09h
int 21h
l6: mov ah,01h
int 21h
cmp al,0dh ;when receive 'enter' cease the input
jZ l7
sub al,30h
jc next2
cmp al,0ah
jnc next2
mov ah,0
mov buf,ax
mov ax,y+2
mul bx
mov y+2,ax ;much the same as 'input1'
mov ax,y
mov dx,0
mul bx
add ax,buf
mov y,ax
adc y+2,dx
loop l6
jmp l7
next2: lea dx,err
mov ah,09h
int 21h
l7: mov dl,13
mov ah,02h
int 21h
mov dl,10
mov ah,02h
int 21h
ret
input2 endp
;################ select oprator #####################
select proc near ;select from 1 to 4
lea dx,opr ; 1----add
mov ah,09h ; 2----subtract
int 21h ; 3----multiply
mov ah,01h ; 4----divided by
int 21h
sub al,30h
cmp al,1
jc next3
cmp al,7
jnc next3
mov operator,al
ret
next3: lea dx,err
mov ah,09h
int 21h
ret
select endp
;#################### add ############################
a proc near
mov ax,x
add ax,y ;simply add x and y
mov result,ax ;keep the result
mov ax,x+2
adc ax,y+2
mov result+2,ax
lea dx,res ;output
mov ah,09h
int 21h
call output1
ret
a endp
;############### subtract ############################
s proc near
mov ax,x+2
cmp ax,y+2 ;compare x and y
jnbe l8 ;if x >= y, sign = 0, result = x - y
jb l9 ;if x < y, sign = 1, result = y - x
mov ax,x
cmp ax,y
jb l9
l8: mov ax,x
sub ax,y
mov result,ax
mov ax,x+2
sbb ax,y+2
mov result+2,ax
ret
l9: mov sign,1 ;result is negative
mov ax,y
sub ax,x
mov result,ax ;keep the result
mov ax,y+2
sbb ax,x+2
mov result+2,ax
lea dx,res ;output
mov ah,09h
int 21h
call output1
ret
s endp
;############## multiply ##############################
m proc near
clc
mov ax,x
mov dx,0
mov bx,y
mul bx ; x*y --->result,result+2
mov result,ax
mov result+2,dx
mov ax,x+2
mov dx,0
mul bx ; (x+2)*y --->result+2,result+4
add result+2,ax
adc result+4,dx
mov ax,x
mov dx,0
mov bx,y+2
mul bx ; x*(y+2) --->result+2,result+4
add result+2,ax
adc result+4,dx
mov ax,x+2
mov dx,0
mul bx ; (x+2)*(y+2) --->result+4,result+6
adc result+4,ax
adc result+6,dx
lea dx,res ;calculate and output
mov ah,09h
int 21h
call output1
ret
m endp
;############### divided by ############################
d proc near ;result+4,result+6 is the quotient, result,result+2 is the remain
mov cx,0 ;cx reserve result+4's value
mov dx,0 ;dx reserve result+6's value
cmp y+2,0
jnZ l10
cmp y,0
jnZ l10
lea dx,err
mov ah,09h
int 21h
ret
l10: mov ax,x+2 ;compare x and y
cmp ax,y+2 ;if x >= y
jnbe l13 ;then (cx)+1 --> cx, and (dx) + carry ---> dx
je l12 ;if x < y
l11: mov ax,x ;then x--->result,result+2
mov result,ax ;and (cx),(dx) --->result+4,result+6
mov ax,x+2
mov result+2,ax
mov result+4,cx
mov result+6,dx
lea dx,res ; output
mov ah,09h
int 21h
call output2
ret
l12: mov ax,x
cmp ax,y
jnb l13
jmp l11
l13: add cx,1
adc dx,0
mov ax,x
sub ax,y
mov x,ax
mov ax,x+2
sbb ax,y+2
mov x+2,ax
jmp l10
ret
d endp
;############### divided by ############################
kcf proc near
clc
mov cx,x
mov dx,0
mov result,cx
vac: mov ax,result
mov z,ax
mov bx,x
mul bx
mov result,ax
mov result+2,dx
mov ax,x+2
mov dx,0
mul bx
add result+2,ax
adc result+4,dx
mov ax,x
mov dx,0
mov bx,z+2
mul bx
add result+2,ax
adc result+4,dx
mov ax,x+2
mov dx,0
mul bx
adc result+4,ax
adc result+6,dx
mov cx,y
sub cx,1
mov y,cx
cmp cx,1
jnz vac
lea dx,res
mov ah,09h
int 21h
call output1
ret
kcf endp
;############### divided by ############################
kpf proc near
mov bx,6
mov ax,x
mul bx
mov si,ax
mov ax,kkk[si]
mov result+4,ax
mov ax,kkk[si+2]
mov result+2,ax
mov ax,kkk[si+4]
mov result,ax
lea dx,res
mov ah,09h
int 21h
call output3
kpf endp
;############## output1(for add,subtract,multiply) ##########
output1 proc near ;similar to the division
mov dl,0
mov bx,0 ;compare with 10^n,(0<= n <= 11)
mov si,0
mov al,sign ;if (result >= 10^n)
cmp al,1
jnZ l14 ;{ (dl)+1 ---> dl
mov dl,'-'
mov ah,02h ; result - 10^n ---> [result]
int 21h
mov dl,0 ; compare with 10^n again }
l14: mov ax,result+4
cmp ax,dcb[si] ;else
jnbe l16
jb l15 ;{ (dl) ---> outstring[bx]
mov ax,result+2
cmp ax,dcb[si+2] ; (si)+6 ---> si
jnbe l16
jb l15 ; (bx)+1 ---> bx
mov ax,result
cmp ax,dcb[si+4] ; compare with 10^n-1 }
jnb l16
l15: mov outstring[bx],dl
add si,6
mov dl,0
inc bx
cmp bx,12
jnZ l14
jmp l17
l16: inc dl
mov ax,result
sub ax,dcb[si+4]
mov result,ax
mov ax,result+2
sbb ax,dcb[si+2]
mov result+2,ax
mov ax,result+4
sbb ax,dcb[si]
mov result+4,ax
jmp l14
l17: mov cx,12
mov si,0
l18: mov dl,outstring[si] ;output the bcd string
cmp dl,0
jne l19
cmp flag,0
jne l19
jmp l20
l19: mov flag,1
add dl,30h
mov ah,02h
int 21h
l20: inc si
loop l18
cmp flag,0
jne l21
mov dl,'0'
mov ah,02h
int 21h
l21: mov flag,0
ret
output1 endp
;########### output2 (for divided) ######################
output2 proc near
mov ax,result ;first output the quotient
mov buf,ax
mov ax,result+2
mov buf+2,ax
mov ax,result+4
mov result,ax
mov ax,result+6
mov result+2,ax
mov result+4,0
mov result+6,0
call output1
mov dl,'.' ;then output the remain
mov ah,02h
int 21h
mov dl,'.'
mov ah,02h
int 21h
mov dl,'.'
mov ah,02h ;use the output1 twice
int 21h
mov ax,buf
mov result,ax
mov ax,buf+2
mov result+2,ax
call output1
ret
output2 endp
;################ repeat? ##############################
output3 proc near ;similar to the division
mov dl,0
mov bx,0 ;compare with 10^n,(0<= n <= 11)
mov si,0
mov al,sign ;if (result >= 10^n)
cmp al,1
jnZ l144 ;{ (dl)+1 ---> dl
mov dl,'-'
mov ah,02h ; result - 10^n ---> [result]
int 21h
mov dl,0 ; compare with 10^n again }
l144: mov ax,result+4
cmp ax,dcb[si] ;else
jnbe l166
jb l155 ;{ (dl) ---> outstring[bx]
mov ax,result+2
cmp ax,dcb[si+2] ; (si)+6 ---> si
jnbe l166
jb l155 ; (bx)+1 ---> bx
mov ax,result
cmp ax,dcb[si+4] ; compare with 10^n-1 }
jnb l166
l155: mov outstring[bx],dl
add si,6
mov dl,0
inc bx
cmp bx,12
jnZ l144
jmp l177
l166: inc dl
mov ax,result
sub ax,dcb[si+4]
mov result,ax
mov ax,result+2
sbb ax,dcb[si+2]
mov result+2,ax
mov ax,result+4
sbb ax,dcb[si]
mov result+4,ax
jmp l144
l177: mov cx,12
mov si,0
l188: mov dl,outstring[si] ;output the bcd string
cmp dl,0
jne l199
cmp flag,0
jne l199
jmp l200
l199:
mov flag,1
add dl,30h
mov ah,02h
int 21h
l200: cmp si,8
jz l1999
looo : inc si
loop l188
cmp flag,0
jne l211
mov dl,'0'
mov ah,02h
int 21h
l1999:mov dl,'.'
mov ah,02h
int 21h
jmp looo
l211: mov flag,0
ret
output3 endp
;########################################################
re proc near
lea dx,again
mov ah,09h
int 21h
mov ah,01h
int 21h
cmp al,'Y'
jnZ l22
mov tag,1
ret
l22: cmp al,'y'
jnZ l23
mov tag,1
ret
l23: ret
re endp
;########################################################
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -