📄 cal.asm.bak
字号:
mov cx,lenth
mov edi,_Var
StdNum10: ;find the first byte 00h
inc edi
mov dl,[edi]
cmp dl,00h
jnz StdNum10
mov ecx,00000000h
mov cx,lenth
mov esi,_Var
add esi,ecx
StdNum20: ;save from right to left
mov dl,30h
cmp edi,_Var ;when edi is at the head of @buffer,stop decreasing edi, going on save 30h to the right
jz StdNum30
dec edi
mov dl,[edi]
StdNum30:
dec esi
mov [esi],dl
dec cx
jnz StdNum20
popf
popad
ret
StdNum endp
;--------------------------------------------------------------------------------------------------------------------------------
Initial proc ;Initial num1,num2,result1,result2,dlgflag,sign1,sign2
pushad
mov lenth,MAX
mov cx,lenth
mov edi,offset num1
mov esi,offset num2
Initial10:
mov dl,00h
mov [edi],dl
mov [esi],dl
inc edi
inc esi
dec cx
jnz Initial10
mov cx,lenth
mov edi,offset result1
mov esi,offset result2
Initial20:
mov dl,00h
mov [edi],dl
mov [esi],dl
inc edi
inc esi
dec cx
jnz Initial20
mov edx,00000000h
mov dlgflag,dl
mov flag,0000h
mov count,edx
mov sign1,2bh
mov sign2,2bh
popad
ret
Initial endp
;--------------------------------------------------------------------------------------------------------------------------------
Calculate proc _num1,_num2,_result1,_result2,_sign
pushad
pushf
;;---------------------------modify the input from ascii to binary code
invoke asciitobin,_num1
invoke asciitobin,_num2
;;---------------------------operate the two numbers
cmp _sign,0000002ah
jnz Calculate10
invoke multiplication, _num1,_num2,_result1,_result2
jmp Calculate40
Calculate10:
cmp _sign,0000002bh
jnz Calculate20
invoke addition,_num1,_num2,_result2
jmp Calculate40
Calculate20:
cmp _sign,0000002dh
jnz Calculate30
invoke subtraction,_num1,_num2,_result2
jmp Calculate40
Calculate30:
cmp _sign,0000002fh
jnz Calculate40
invoke divition,_num1,_num2,_result1,_result2
Calculate40:
;;---------------------------modify the output binary code from to ascii
cmp _sign,0000002ah
jz Calculate50
cmp _sign,0000002fh
jz Calculate60
cmp _sign,0000002bh
jz Calculate70
cmp _sign,0000002dh
jz Calculate70
jmp Calculate80
Calculate50:
mov ax,lenth ;modify lenth
shl ax,01h
mov lenth,ax
invoke bintoascii,_result1
mov ax,lenth ;modify lenth
shr ax,01h
mov lenth,ax
jmp Calculate80
Calculate60:
invoke bintoascii,_result1
Calculate70:
invoke bintoascii,_result2
Calculate80:
popf
popad
ret
Calculate endp
;--------------------------------------------------------------------------------------------------------------------------------
asciitobin proc stdcall,_Var:dword
pushad
pushf
;;---------------------------initialize array temp[] as 00000...
mov edi,offset temp3
mov cx,lenth
asciitobin10:
mov al,00h
mov ebx,00h
mov bx,cx
mov [edi+ebx-1],al
dec cx
jnz asciitobin10
;;---------------------------
mov cx,lenth ;ascii to BCD
mov edi,_Var
asciitobin20:
mov al,[edi]
and al,0fh
mov [edi],al
inc edi
dec cx
jnz asciitobin20
;;---------------------------
mov cx,lenth
mov edi,_Var
asciitobin30: ;num=(...(num[0]*0ah+num[1])*0ah)*...)+num[max-1]
;temp1=temp1*0ah+num[i]
;;; num is an array of ascii '0'~'9', therefor the value: num=(...(num[0]*10+num[1])*10)*...)+num[max-1] is
;;; smaller than fff...f (max f). temp3 is big enough in size for num as hexadecimal code
mov dl,byte ptr [edi]
invoke multiply,addr temp3,0ah,addr temp1
push cx
push edi ;temp3=temp1[lenth,2*lenth-1]
mov cx,lenth
mov edi,offset temp3
mov esi,offset temp2
asciitobin40:
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec cx
jnz asciitobin40
pop edi
pop cx
pushf ;save zf
mov ebx,00h ;temp3=temp3+num[i]
mov bx,lenth
mov al,byte ptr temp3[ebx-1]
add al,dl
mov byte ptr temp3[ebx-1],al
dec ebx
asciitobin50:
adc byte ptr temp3[ebx-1],00h
dec ebx
jnz asciitobin50
popf ;pop zf
inc edi
dec cx
jnz asciitobin30
;;---------------------------
mov cx,lenth
mov edi,_Var
mov esi,offset temp3
asciitobin60:
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec cx
jnz asciitobin60
popf
popad
ret
asciitobin endp
;--------------------------------------------------------------------------------------------------------------------------------
bintoascii proc _Var
pushad
pushf
mov cx,lenth
mov esi,_Var
mov edi,offset temp1
bintoascii00:
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec cx
jnz bintoascii00
;;;result is not set to 000...0 because there will be more numbers in an uncompressed bcd code than a hexadecimal code,
;;;thus, the old numbers in result will all be replace in the process
mov esi,_Var ;start division
mov ecx,00000000h
mov cx,lenth
add esi,ecx
mov dh,0ah
bintoascii10:
push ecx
; a division round starts
; in every division, the quotient will be same in temp1 sequently as a divident later, and the last reminder
; will be saved as result(the ASCII code)
mov cx,lenth
mov edi,offset temp1
mov ah,00h ;ah is set to 00h, later the remind of a early division will be left in ah
mov dl,00h ;dl is used to save cx(dl=cl) the first time when the quotient al!=0
bintoascii20:
mov al,[edi]
div dh ;ax/dh, leaving quotient in al, reminder in ah
cmp al,00h ;the quotient al!=0 ?
jz bintoascii30
cmp dl,00h ;dl is modified to 00h at the beginning
jnz bintoascii30
mov dl,cl ;save cx: the first time when quotient al!=0
bintoascii30:
mov [edi],al ;save the quotient al, temp1 will be used as a divident later
inc edi
dec cx
jnz bintoascii20
pop ecx
dec esi
mov [esi],ah ;***** ;ah is the last reminder of a division round(a division round is between bintoascii10)
dec cx
jz bintoascii50 ;NOT NECESSARY, JUST PREVENT ESI FROM DECREASING TOO MUCH WHEN PROGRAM FAILS TO WORK PROPERLY
cmp dl,00h
jnz bintoascii10
bintoascii50:
mov cx,lenth
mov edi,_Var
bintoascii40:
mov al,[edi]
xor al,30h
mov [edi],al
inc di
dec cx
jnz bintoascii40
popf
popad
ret
bintoascii endp
;--------------------------------------------------------------------------------------------------------------------------------
addition proc _Var1,_Var2,_Var3
pushad
pushf
mov cx,lenth
addition10:
mov ebx,0000h
mov bx,cx
mov esi,_Var1
mov ah,[esi+ebx-1]
mov esi,_Var2
mov al,[esi+ebx-1]
adc ah,al
mov esi,_Var3
mov [esi+ebx-1],ah
dec cx
jnz addition10
;the problem of overflow is unsolved
popf
popad
ret
addition endp
;--------------------------------------------------------------------------------------------------------------------------------
subtraction proc _Var1,_Var2,_Var3
pushad
pushf
mov cx,lenth
subtraction10:
mov ebx,00h
mov bx,cx
mov esi,_Var1
mov ah,[esi+ebx-1]
mov esi,_Var2
mov al,[esi+ebx-1]
sbb ah,al
mov esi,_Var3
mov [esi+ebx-1],ah
dec cx
jnz subtraction10
;the problem of overflow is unsolved
popf
popad
ret
subtraction endp
;--------------------------------------------------------------------------------------------------------------------------------
multiplication proc _Var1,_Var2,_Var3,_Var4
pushad
pushf
;CCCCCC=AAA*BBB
mov cx,lenth
mov edi,_Var2
multiplication10:
mov eax,00h
mov al,[edi]
invoke multiply,_Var1,eax,offset temp1 ;AAA*B
invoke moveleft,_Var3,02h ;CCCCCC*10H
mov ax,lenth ;modify lenth
shl ax,01h
mov lenth,ax
invoke addition,_Var3,offset temp1,_Var3 ;CCCCCC=CCCCCC+AAA*B
mov ax,lenth ;modify lenth
shr ax,01h
mov lenth,ax
inc edi
dec cx
jnz multiplication10
popf
popad
ret
multiplication endp
;--------------------------------------------------------------------------------------------------------------------------------
divition proc _Var1,_Var2,_Var3,_Var4
pushad
pushf
;----------------------------
mov cx,lenth
mov edi,_Var4
mov esi,_Var1
divition10:
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec cx
jnz divition10
;;---------------------------
mov ecx,00h
mov cx,lenth
mov esi,_Var4
add esi,ecx
mov al,cl
mov dh,08h
mul dh
mov cx,ax
divition20:
invoke shlresult,_Var3 ;SHL result
mov flag,0000h
invoke bigger,_Var2,_Var3,offset flag ;examine if result1>num2
cmp flag,1111h ; |
jnz divition30 ; |
mov al,[esi-1] ; result=result+01h
add al,01h ; |
mov [esi-1],al ; |
invoke subtraction,_Var3,_Var2,_Var3; result1=result1-num2
divition30:
dec cx
jnz divition20
;;---------------------------
popf
popad
ret
divition endp
;--------------------------------------------------------------------------------------------------------------------------------
multiply proc _Var1,_Var2,_Var3
pushad
pushf
;;---------------------------initialize array temp[] as 00000...
mov edi,_Var3
mov cx,lenth
shl cx,01h
multiply10:
mov al,00h
mov ebx,00h
mov bx,cx
mov [edi+ebx-1],al
dec cx
jnz multiply10
;;---------------------------
mov cx,lenth
mov edi,_Var1
multiply20:
pushf ;save zf
mov al,[edi] ;temp=temp*10h+ai*bi temp->address2
mov ah,00h
mul _Var2 ;dx=ai*bi
mov dx,ax
invoke moveleft,_Var3 ,02h ;temp=temp*10h
mov ebx,00h ;temp=temp+ai*bi
mov bx,lenth
shl bx,01h
mov esi,_Var3
mov al,byte ptr [esi+ebx-1]
mov ah,byte ptr [esi+ebx-2]
add ax,dx
mov byte ptr [esi+ebx-1],al
mov byte ptr [esi+ebx-2],ah
dec ebx
dec ebx
multiply30:
adc byte ptr [esi+ebx-1],00h
dec bx
jnz multiply30
popf ;pop zf
inc edi
dec cx
jnz multiply20
popf
popad
ret
multiply endp
;--------------------------------------------------------------------------------------------------------------------------------
bigger proc _Var1,_Var2,_Var3
pushad
pushf
mov cx,lenth
mov edi,_Var1
mov esi,_Var2
bigger10:
mov ah,[edi]
mov al,[esi]
cmp ah,al
jnz bigger20
inc edi
inc esi
dec cx
jnz bigger10
bigger20:
cmp ah,al
jnbe bigger30 ;flag is set to 0000h before this function is called
mov ax,1111h
mov edi,_Var3
mov [edi],ax
bigger30:
popf
popad
ret
bigger endp
;--------------------------------------------------------------------------------------------------------------------------------
shlresult proc _Var
pushad
pushf
mov edi,_Var
mov cx,lenth
shl cx,01h
clc
shlresult10:
mov ebx,00h
mov bx,cx
mov al,[edi+ebx-1]
rcl al,01h
mov [edi+ebx-1],al
dec cx
jnz shlresult10
popf
popad
ret
shlresult endp
;--------------------------------------------------------------------------------------------------------------------------------
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -