📄 cal.asm
字号:
title calculator
;--------------------------------------------------------------------------------------------------------------------------------
; purpose term project
; programmer sun
; filename cal.asm, cal.res resource.h
; compiler masm32
; type win32
;--------------------------------------------------------------------------------------------------------------------------------
.386
.model flat,stdcall
option casemap:none ;case sensitive
;--------------------------------------------------------------------------------------------------------------------------------
;include files need .inc and .lib files in masm32
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.inc
;--------------------------------------------------------------------------------------------------------------------------------
;#define
MAX equ 0ch
;the size of the input number
;defined in resource.h, is used to link with cal.res
IDD_DIALOG equ 101
IDC_BUTTON_1 equ 1001
IDC_BUTTON_2 equ 1002
IDC_BUTTON_3 equ 1003
IDC_BUTTON_4 equ 1004
IDC_BUTTON_5 equ 1005
IDC_BUTTON_6 equ 1006
IDC_BUTTON_7 equ 1007
IDC_BUTTON_8 equ 1008
IDC_BUTTON_9 equ 1009
IDC_BUTTON_0 equ 1000
IDC_BUTTON_SIGN equ 1010
IDC_BUTTON_AC equ 1011
IDC_BUTTON_ADD equ 1012
IDC_BUTTON_SUB equ 1013
IDC_BUTTON_MUL equ 1014
IDC_BUTTON_DIV equ 1015
IDC_BUTTON_EQU equ 1016
IDC_EDIT_DISPLAY equ 1017
IDC_EDIT_INFO equ 1018
;--------------------------------------------------------------------------------------------------------------------------------
;definitions
.data
count dword 00000000h ;count:save the length of the input number
dlgflag db 00h
; dlgflag 00h num1,num2 is not empty
; dlgflag 01h num1 is assigned,num2 is empty,operator is not assigned
; dlgflag 02h num1 and num2 are assigned
; dlgflag 03h num1 is assigned,num2 is empty,operator is assigned
num1 db MAX dup(0),0 ;inout number: in ASCII code first \
num2 db MAX dup(0),0 ;and is changed to binary code to operate
sign1 db '+'
sign2 db '+'
flag word 0000h ;flag used in biger proc,Var1,Var2,@flag: 0000h--Var1>Var2; 1111h--Var1<Var2
lenth word MAX
result1 db MAX dup(0) ;result number,to output \
result2 db MAX dup(0),0 ;extended result1 is reminder of a division
temp1 db MAX dup(0) ;temporary number used in operation: in binary code
temp2 db MAX dup(0),0 ;will be set to 000...0 before use
temp3 db MAX dup(0),0
.data?
resultsign db ? ;the sign of the result
sign db ? ;the operator between the two numbers
hInstance dword ? ;handle of Dialog
.const ;information
OverScale db 'The input number is overscale.',0
Warning db 'Warning!',0
Blank db 0
;--------------------------------------------------------------------------------------------------------------------------------
;codes
.code
ProcDlgMain proto hWnd:dword,wMsg:dword,wParam:dword,lParam:dword
moveright proto _Var:dword ;move number right one byte
moveleft proto _Var1:dword,_Var2:dword ;move number left one byte
StdNum proto _Var:dword ;@buffer is save in left to right sequence, change num to right to left sequence
Initial proto
;;;main function
Calculate proto _num1:dword,_num2:dword,_result1:dword,_result4:dword,_sign:dword
asciitobin proto _Var:dword ;change num from ASCII code to Binary code
bintoascii proto _Var:dword ;change result from Binary code to ASCII code
addition proto _Var1:dword,_Var2:dword,_Var3:dword
subtraction proto _Var1:dword,_Var2:dword,_Var3:dword
multiplication proto _Var1:dword,_Var2:dword,_Var3:dword,_Var4:dword ;multiple bits AAAAAA*BBBBBB
divition proto _Var1:dword,_Var2:dword,_Var3:dword,_Var4:dword
multiply proto _Var1:dword,_Var2:dword,_Var3:dword ;single bit AAAAAA*B
bigger proto _Var1:dword,_Var2:dword,_Var3:dword ;tell if Var1>Var2
shlresult proto _Var:dword
;--------------------------------------------------------------------------------------------------------------------------------
ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @buffer[MAX+2]:byte
local @address:dword
local @numaddress1:dword ;address of num to input as the first number in proc calculate
local @numaddress2:dword
local @temp:byte
local @distinction[4]:byte
;distinction[]:save sign1,sign,sign2,(num1>num2) to imply the sequence of @numaddress, the ultimate operator between
;the two numbers, and whether the sign of the result is positive or negative
;distinction[0~3]: sign1,sign,sign2,bigger
;sign1: sign of num1 is positive distinction[0]
;sign operator is + or -; +:1,-:0 distinction[1]
;sign2: sign of num2 is positive distinction[2]
;bigger: num1>num2 distinction[3]
;A: the case that num1 is the first operand,num2 is the second
;B: operator between the two operands
;C: the sign of the result
;sign1 sign sign2 bigger A B C
;1 1 1 1&0 1 1 1
;1 1 0 1 1 0 1
;1 1 0 0 0 0 0
;0 1 1 1 1 0 0
;0 1 1 0 0 0 1
;0 1 0 1&0 1 1 0
;1 0 1 1 1 0 1
;1 0 1 0 0 0 0
;1 0 0 1&0 1 1 1
;0 0 1 1&0 1 1 0
;0 0 0 1 1 0 0
;0 0 0 0 0 0 1
;we can use K-MAP method to how out the relations between distinction[0~3] and A,B,C
;A=bigger+sign1^(sign)^(sign2)+(sign1)^sign^(sign2)+(sign1)^(sign)^sign2+sign1^sign^sign2
;B=sign1^(sign)^(sign2)+(sign1)^sign^(sign2)+(sign1)^(sign)^sign2+sign1^sign^sign2
;C=sign1^bigger+(sign)^(sign2)^(bigger)+sign^sign2^(bigger)
;;;(sign)= ┐sign
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
;--------------------------------------------------------------------------------------------------------------------------------
.elseif eax == WM_INITDIALOG
invoke SendDlgItemMessage,hWnd,IDC_EDIT_DISPLAY,EM_SETREADONLY,TRUE,NULL
invoke SendDlgItemMessage,hWnd,IDC_EDIT_INFO,EM_SETREADONLY,TRUE,NULL
;--------------------------------------------------------------------------------------------------------------------------------
.elseif eax == WM_COMMAND
mov eax,wParam
.if (ax==IDC_BUTTON_1) || (ax==IDC_BUTTON_2) || (ax==IDC_BUTTON_3) || \
(ax==IDC_BUTTON_4) || (ax==IDC_BUTTON_5) || (ax==IDC_BUTTON_6) || \
(ax==IDC_BUTTON_7) || (ax==IDC_BUTTON_8) || (ax==IDC_BUTTON_9) || \
(ax==IDC_BUTTON_0)
inc count
cmp count,MAX
jnbe ProcDlgMain10
.if dlgflag==00h
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,offset Blank
mov dl,01h
mov dlgflag,dl
.elseif dlgflag==03h
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,offset Blank
mov dl,02h
mov dlgflag,dl
.endif
invoke GetDlgItemText,hWnd,IDC_EDIT_DISPLAY,\ ;put EDIT TEXT to @buffer
addr @buffer,sizeof @buffer
mov eax,wParam ;get input number
.if ax==IDC_BUTTON_1
mov dl,31h
.elseif ax==IDC_BUTTON_2
mov dl,32h
.elseif ax==IDC_BUTTON_3
mov dl,33h
.elseif ax==IDC_BUTTON_4
mov dl,34h
.elseif ax==IDC_BUTTON_5
mov dl,35h
.elseif ax==IDC_BUTTON_6
mov dl,36h
.elseif ax==IDC_BUTTON_7
mov dl,37h
.elseif ax==IDC_BUTTON_8
mov dl,38h
.elseif ax==IDC_BUTTON_9
mov dl,39h
.elseif ax==IDC_BUTTON_0
mov dl,30h
.endif
mov ebx,count
mov dh,00h
mov @buffer[ebx-1],dl
mov @buffer[ebx],dh
;set text @buffer
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,addr @buffer
jmp ProcDlgMain20
ProcDlgMain10:
invoke MessageBox,NULL,offset OverScale,offset Warning,MB_OK
ProcDlgMain20:
;---------------------------------------------------------------------------------------------------
.elseif ax==IDC_BUTTON_SIGN
.if (dlgflag==01h) || (dlgflag==02h)
invoke GetDlgItemText,hWnd,IDC_EDIT_DISPLAY,\
addr @buffer,sizeof @buffer
;get text to @buffer
.if dlgflag==01h ;write sign to right place:sign1 or sign2
.if sign1==2bh
mov dl,2dh
mov sign1,dl
.else
mov dl,2bh
mov sign1,dl
.endif
.else
.if sign2==2bh
mov dl,2dh
mov sign2,dl
.else
mov dl,2bh
mov sign2,dl
.endif
.endif
mov @temp,dl
mov dh,@buffer
.if dh==2dh ;the first byte of @buffer is '-',negative sign
invoke moveleft,addr @buffer,01h
dec count
mov dl,00h
mov ebx,count
mov @buffer[ebx],dl
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,addr @buffer
.else ;the first byte of @buffer is a number: positive sign is not not output
invoke moveright,addr @buffer
mov dl,@temp
mov @buffer,dl
inc count
mov dl,00h
mov ebx,count
mov @buffer[ebx],dl
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,addr @buffer
.endif
.endif
;---------------------------------------------------------------------------------------------------
.elseif ax==IDC_BUTTON_AC
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,offset Blank
invoke SetDlgItemText,hWnd,IDC_EDIT_INFO,offset Blank
call Initial
;---------------------------------------------------------------------------------------------------
.elseif (ax==IDC_BUTTON_ADD) || (ax==IDC_BUTTON_SUB) || (ax==IDC_BUTTON_MUL) \
|| (ax==IDC_BUTTON_DIV)
.if (dlgflag==01h) || (dlgflag==03h)
mov edx,00000000h
mov count,edx
mov eax,wParam ;assign operator
.if ax==IDC_BUTTON_ADD
mov dl,2bh
.elseif ax==IDC_BUTTON_SUB
mov dl,2dh
.elseif ax==IDC_BUTTON_MUL
mov dl,2ah
.elseif ax==IDC_BUTTON_DIV
mov dl,2fh
.endif
mov sign,dl ;display selected operator
invoke SetDlgItemText,hWnd,IDC_EDIT_INFO,offset sign
;dlgflag->03h step changed
mov dlgflag,03h
;save the first number
invoke GetDlgItemText,hWnd,IDC_EDIT_DISPLAY,\
addr @buffer,sizeof @buffer
mov cx,lenth
mov edi,offset num1
lea esi,@buffer
;if the first byte of @buffer is '-', then copy from the second byte
mov dl,[esi]
.if dl==2dh
inc esi
dec cx
.endif
ProcDlgMain30:
mov dl,[esi]
mov [edi],dl
inc esi
inc edi
dec cx
jnz ProcDlgMain30
.endif
;---------------------------------------------------------------------------------------------------
.elseif ax==IDC_BUTTON_EQU
.if dlgflag==02h
invoke SetDlgItemText,hWnd,IDC_EDIT_INFO,offset Blank
invoke GetDlgItemText,hWnd,IDC_EDIT_DISPLAY,\
addr @buffer,sizeof @buffer
mov cx,lenth
mov edi,offset num2
lea esi,@buffer
mov dl,[esi]
.if dl==2dh
inc esi
dec cx
.endif
ProcDlgMain40:
mov dl,[esi]
mov [edi],dl
inc esi
inc edi
dec cx
jnz ProcDlgMain40
invoke StdNum,offset num1
invoke StdNum,offset num2
;after the input round, get distinction, in order to determine
;how to execute the operands
mov flag,0000h
invoke bigger,offset num1,offset num2,offset flag
.if flag==0000h ;num1>num2------>bigger(element 4)
mov @distinction[3],01h
.else
mov @distinction[3],00h
.endif
.if sign1==2bh ;sign of num1------>sign1(element 1)
mov @distinction[0],01h
.else
mov @distinction[0],00h
.endif
.if sign==2bh ;operator------------>sign(element 2)
mov @distinction[1],01h
.elseif sign==2dh
mov @distinction[1],00h
.elseif sign==2ah
mov @distinction[1],02h
.elseif sign==02fh
mov @distinction[1],03h
.endif
.if sign2==2bh ;sign of num2------->sign2(element 3)
mov @distinction[2],01h
.else
mov @distinction[2],00h
.endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;use K-MAP method, we can get
;A=bigger+sign1^(sign)^(sign2)+(sign1)^sign^(sign2)+(sign1)^(sign)^sign2+sign1^sign^sign2
mov @numaddress1,offset num2
mov @numaddress2,offset num1
.if (@distinction[3]==01h) || (@distinction[1]==02h) || (@distinction[1]==03h) || \
((@distinction[0]==01h) && (@distinction[1]==00h) && (@distinction[2]==00h)) || \
((@distinction[0]==00h) && (@distinction[1]==01h) && (@distinction[2]==00h))
mov @numaddress1,offset num1
mov @numaddress2,offset num2
.endif
.if ((@distinction[0]==00h) && (@distinction[1]==00h) && (@distinction[2]==01h)) || \
((@distinction[0]==01h) && (@distinction[1]==01h) && (@distinction[2]==01h))
mov @numaddress1,offset num1
mov @numaddress2,offset num2
.endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;use K-MAP method, we can get
;B=sign1^(sign)^(sign2)+(sign1)^sign^(sign2)+(sign1)^(sign)^sign2+sign1^sign^sign2
mov sign,2dh
.if ((@distinction[0]==01h) && (@distinction[1]==00h) && (@distinction[2]==00h)) || \
((@distinction[0]==00h) && (@distinction[1]==01h) && (@distinction[2]==00h))
mov sign,2bh
.elseif ((@distinction[0]==00h) && (@distinction[1]==00h) && (@distinction[2]==01h)) || \
((@distinction[0]==01h) && (@distinction[1]==01h) && (@distinction[2]==01h))
mov sign,2bh
.elseif @distinction[1]==02h
mov sign,2ah
.elseif @distinction[1]==03h
mov sign,2fh
.endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;use K-MAP method, we can get
;C=sign1^bigger+(sign)^(sign2)^(bigger)+sign^sign2^(bigger)
mov resultsign,2dh
.if ((@distinction[1]==00h) && (@distinction[2]==00h) && (@distinction[3]==00h)) || \
((@distinction[1]==01h) && (@distinction[2]==01h) && (@distinction[3]==00h)) || \
((@distinction[0]==01h) && (@distinction[3]==01h) && ((@distinction[1]==00h) || (@distinction[1]==01h)))
mov resultsign,2bh
.elseif ((@distinction[0]==01h) && (@distinction[1]==02h) && (@distinction[2]==01h)) || \
((@distinction[0]==00h) && (@distinction[1]==02h) && (@distinction[2]==00h))
mov resultsign,2bh
.elseif ((@distinction[0]==01h) && (@distinction[1]==03h) && (@distinction[2]==01h)) || \
((@distinction[0]==00h) && (@distinction[1]==03h) && (@distinction[2]==00h))
mov resultsign,2bh
.endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
mov edx,00000000h
mov dl,sign
invoke Calculate,@numaddress1,@numaddress2,offset result1,offset result2,edx
.if (sign==2bh) || (sign==2dh)
.if resultsign==2dh
mov dl,02dh
mov result2,dl
.endif
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,offset result2
.elseif sign==2fh
.if resultsign==2dh
mov dl,02dh
mov result2,dl
.endif
.if sign1==2dh
mov dl,02dh
mov result1,dl
.endif
mov cx,lenth
lea edi,@address
mov esi,offset result1
ProcDlgMain60:
mov dl,[esi]
mov [edi],dl
inc edi
inc esi
dec cx
jnz ProcDlgMain60
mov dl,00h
mov [edi],dl
invoke SetDlgItemText,hWnd,IDC_EDIT_INFO,addr @address
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,offset result2
.elseif sign==2ah
.if resultsign==2dh
mov dl,02dh
mov result1,dl
.endif
invoke SetDlgItemText,hWnd,IDC_EDIT_DISPLAY,offset result1
.endif
call Initial
.endif
;--------------------------------------------------------------------------------------------------
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
ProcDlgMain endp
;--------------------------------------------------------------------------------------------------------------------------------
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_DIALOG,NULL,offset ProcDlgMain,NULL
invoke ExitProcess,NULL
;--------------------------------------------------------------------------------------------------------------------------------
moveright proc _Var
pushad
pushf
mov ecx,00000000h
mov cx,lenth
dec cx
mov edi,_Var
add edi,ecx
moveright10:
dec edi
mov ah,byte ptr [edi-1]
mov byte ptr [edi],ah
dec cx
jnz moveright10
dec edi
mov dl,00h
mov [edi],dl
popf
popa
ret
moveright endp
;--------------------------------------------------------------------------------------------------------------------------------
moveleft proc _Var1,_Var2
pushad
pushf
mov cx,lenth
cmp _Var2,01h ;if _Var2==02h, mean the scale is 2*MAX
jz moveleft10
shl cx,01h
moveleft10:
dec cx
mov edi,_Var1
moveleft20:
mov ah,byte ptr [edi+1]
mov byte ptr [edi],ah
inc edi
dec cx
jnz moveleft20
mov ah,00h
mov byte ptr [edi],ah
popf
popa
ret
moveleft endp
;--------------------------------------------------------------------------------------------------------------------------------
StdNum proc _Var
pushad
pushf
; @bufer is saved from left to right
; find the first byte that is 00h
; from that byte backward, save them from right to left
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -