汇编语言程序设计——仿win7计算器(功能部分)
来源:互联网 发布:手机调试js 编辑:程序博客网 时间:2024/05/16 10:41
下面代码实现的计算机基本的功能,包括加、减、乘、除、求倒、开方、百分比、记忆相关功能等,支持快捷键,显示也可以分段显示,如下图。
界面部分源码:http://blog.csdn.net/zhangjiajie023/article/details/7728268
整体设计参考自:http://www.cnblogs.com/kingwolfofsky/archive/2011/07/07/2100375.html
不多说了,下面贴出源代码,挺多的:
;********************************************; 仿win7计算器 *; *; CS0**** *; U200915** *;********************************************.386.model flat,stdcalloption casemap:none;********************************************include d:\masm32\include\windows.incinclude d:\masm32\include\shell32.incinclude d:\masm32\include\user32.incinclude d:\masm32\include\comctl32.incinclude d:\masm32\include\masm32.incinclude d:\masm32\include\kernel32.incincludelib d:\masm32\lib\user32.libincludelib d:\masm32\lib\comctl32.libincludelib d:\masm32\lib\masm32.libincludelib d:\masm32\lib\kernel32.libincludelib d:\masm32\lib\shell32.lib;*******************************************IDB_0 EQU 100IDB_1 EQU 101IDB_2 EQU 102IDB_3 EQU 103IDB_4 EQU 104IDB_5 EQU 105IDB_6 EQU 106IDB_7 EQU 107IDB_8 EQU 108IDB_9 EQU 109;------------------------IDB_NEG EQU 110IDB_POINT EQU 111IDB_DIV EQU 112IDB_MUL EQU 113IDB_SUB EQU 114IDB_ADD EQU 115IDB_SQRT EQU 116IDB_PER EQU 117IDB_DAO EQU 118IDB_EQU EQU 119;------------------------IDB_MC EQU 120IDB_MR EQU 121IDB_MS EQU 122IDB_MPLUS EQU 123IDB_MSUB EQU 124IDB_M EQU 125IDB_BACK EQU 126IDB_CE EQU 127IDB_C EQU 128;------------------------IDT_MEMORY EQU 129IDT_RESULT EQU 130;------------------------Icon EQU 1000IDM_COPY EQU 1001IDM_PASTE EQU 1002IDM_STANDARD EQU 1003IDM_SCIENCE EQU 1004IDM_GROUP EQU 1006IDM_HELP EQU 1007IDM_ABOUT EQU 1008IDM_EXIT EQU 1009IDM_KJJ EQU 1010IDM_NOTIFYICON EQU 2000WM_SHELLNOTIFY EQU 2001;**********************函数原型说明***************************WinMain PROTO :DWORD, :DWORD, :DWORD, :DWORD ; 窗口主程序Calculate PROTO :DWORD, :DWORD, :DWORD, :DWORD ; 消息处理程序Init PROTO ; 初始化NumBtn PROTO :DWORD ; 数字按键消息处理程序AddDelNeg PROTO ; 添加或删除‘-’号SavePreData PROTO ; 保存当前文本框中的数据ShowMemory PROTO ; 显示存储信息GetResult PROTO ; 双目运算MemoryFunc PROTO :DWORD ; 记忆加或记忆减GroupNum PROTO ; 数字分组UnGroupNum PROTO ; 数字取消分组 ;****************************数据段****************************.data CommandLine DD 0 Output DB "0",0,40 DUP(0) IsStart DB 0 IsError DB 0 HasPoint DB 0 HasEqual DB 0 ;判断是否存在等号 HasNeg1 DB 0;各数是否有‘-’号 HasNeg2 DB 0 ResultNeg DB 0 MemoryNeg DB 0 IsShowMem DB 0 ;是否显示记忆 IsGroup DB 0 Operator DB '.' ;记录双目运算符 Buffer DB '.' ;用于暂存字符 Memory DQ 0.0 Temporary DQ 0.0 ;临时数据 Operand1 DQ 0.0 ;操作数1 Operand2 DQ 0.0 Result DQ 0.0 NumLittle REAL8 1.0E-12 Num100 REAL8 100.0 ;实数100 NotifyIcon NOTIFYICONDATA<> ;通知栏图标;------------------------------------------------------------ .data? hInstance DD ? hEdit1 DD ? ; 下面输出文本框句柄 hEdit2 DD ? ; 上面输出文本框句柄 hTextM DD ? hMenu DD ? hIcon DD ? hGlobal HANDLE ? pGlobal DB ?;------------------------------------------------------------.const DivError DB "除数不能为0",0 FuncError DB "输入函数无效",0 About DB '作者: 张**', 0ah,0dh,'时间:2010-10-10',0 ShortCuts DB '字母->功能:X->倒数 N->取反 S->开方 E->CE R->C',0ah,0dh, ' Y->MC U->MR I->MS O->M+ P->M-',0 HelpFile DB "help.hlp",0 ProgramName DB "计算器",0 DialogName DB "Calculator",0 MenuName DB "Menu",0 IconName DB "Icon",0 TextM DB 'M',0;----------------------------------------------------------;***************************代码段**************************.code start: ;---------------------------------------------------------- invoke GetModuleHandle,NULL mov hInstance,eax invoke WinMain,hInstance,0,0,SW_SHOWDEFAULT invoke ExitProcess,eax;--------------------------------------------------------- WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hWnd:HWND mov wc.cbSize,sizeof WNDCLASSEX mov wc.style,CS_BYTEALIGNWINDOW or CS_BYTEALIGNWINDOW mov wc.lpfnWndProc,OFFSET Calculate mov wc.cbClsExtra,0 mov wc.cbWndExtra,DLGWINDOWEXTRA mov eax,hInst mov wc.hInstance,eax mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,OFFSET MenuName mov wc.lpszClassName,OFFSET DialogName invoke LoadIcon,hInst,addr IconName mov wc.hIcon,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax mov wc.hIconSm,0 invoke RegisterClassEx,addr wc invoke CreateDialogParam,hInst,addr DialogName,0,addr Calculate,0 mov hWnd,eax invoke ShowWindow,hWnd,CmdShow invoke UpdateWindow,hWnd StartLoop: invoke GetMessage,addr msg,0,0,0 cmp eax,0 je ExitLoop invoke TranslateMessage,addr msg invoke DispatchMessage,addr msg jmp StartLoop ExitLoop: mov eax,msg.wParam ret WinMain endp;---------------------------------------------------------------;---------------------------------------------------------------;消息处理程序用于处理用户消息。;hWin:窗口句柄;uMsg:消息标识;param1 param2:消息所带的参数;---------------------------------------------------------------Calculate proc hWin:DWORD,uMsg:UINT,param1:DWORD,param2:DWORDLOCAL pt:POINT ;------------------------------------------------------- .if uMsg == WM_INITDIALOG ;初始化窗口 invoke GetDlgItem,hWin,IDT_RESULT mov hEdit1,eax invoke GetDlgItem,hWin,IDT_MEMORY mov hEdit2,eax invoke GetDlgItem,hWin,IDB_M mov hTextM,eax invoke LoadIcon,hInstance,addr IconName mov hIcon,eax invoke SendMessage,hWin,WM_SETICON,ICON_SMALL,eax invoke LoadMenu,hInstance,addr MenuName mov hMenu,eax invoke SetMenu,hWin,eax invoke CheckMenuRadioItem,hMenu,IDM_STANDARD,IDM_SCIENCE,IDM_STANDARD,MF_BYCOMMAND ;选中标准型 invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;----------------------------------------------------------- .elseif uMsg == WM_SIZE .if param1==SIZE_MINIMIZED ;最小化 mov NotifyIcon.cbSize,sizeof NOTIFYICONDATA push hWin pop NotifyIcon.hwnd mov NotifyIcon.uID,IDM_NOTIFYICON mov NotifyIcon.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP mov NotifyIcon.uCallbackMessage,WM_SHELLNOTIFY mov eax,hIcon mov NotifyIcon.hIcon,eax invoke lstrcpy,addr NotifyIcon.szTip,addr ProgramName invoke Shell_NotifyIcon,NIM_ADD,addr NotifyIcon .endif ;--------------------------------------------------------------- .elseif uMsg == WM_SHELLNOTIFY .if param1==IDM_NOTIFYICON .if(param2==WM_LBUTTONDOWN) ;鼠标左键按下 invoke ShowWindow,hWin,SW_SHOW invoke Shell_NotifyIcon,NIM_DELETE,addr NotifyIcon .elseif(param2==WM_RBUTTONDOWN) ;鼠标右键按下 invoke GetCursorPos,addr pt invoke GetSubMenu,hMenu,3 invoke TrackPopupMenu,eax,TPM_LEFTALIGN,pt.x,pt.y,NULL,hWin,NULL .endif .endif ;---------------------------------------------------------------- .elseif uMsg == WM_CHAR ;热键操作 mov eax,param1 add eax,IDB_0 sub eax,'0' .if (eax>=IDB_0) && (eax<=IDB_9) invoke Calculate,hWin,WM_COMMAND,eax,0 .elseif (eax==98) invoke Calculate,hWin,WM_COMMAND,IDB_POINT,0 .elseif (eax==95) invoke Calculate,hWin,WM_COMMAND,IDB_ADD,0 .elseif (eax==97) invoke Calculate,hWin,WM_COMMAND,IDB_SUB,0 .elseif (eax==94) invoke Calculate,hWin,WM_COMMAND,IDB_MUL,0 .elseif (eax==97) invoke Calculate,hWin,WM_COMMAND,IDB_DIV,0 .elseif (eax==89) invoke Calculate,hWin,WM_COMMAND,IDB_PER,0 .elseif (eax==60) invoke Calculate,hWin,WM_COMMAND,IDB_BACK,0 .elseif (eax==113) invoke Calculate,hWin,WM_COMMAND,IDB_EQU,0 ;------------------------------------------------- .elseif (eax==140 || eax==172) ; x 倒数1/x invoke Calculate,hWin,WM_COMMAND,IDB_DAO,0 .elseif (eax==135 || eax==167) ; s 开方 invoke Calculate,hWin,WM_COMMAND,IDB_SQRT,0 .elseif (eax==130 || eax==162) ; n 正负 invoke Calculate,hWin,WM_COMMAND,IDB_NEG,0 .elseif (eax==121 || eax==153) ; e 清除当前数据 invoke Calculate,hWin,WM_COMMAND,IDB_CE,0 .elseif (eax==134 || eax==166) ; r 初始化 invoke Calculate,hWin,WM_COMMAND,IDB_C,0 ;------------------------------------------------- .elseif (eax==141 || eax==173) ; y 记忆清零 invoke Calculate,hWin,WM_COMMAND,IDB_MC,0 .elseif (eax==137 || eax==169) ; u 显示记忆 invoke Calculate,hWin,WM_COMMAND,IDB_MR,0 .elseif (eax==125 || eax==157) ; i 记忆当前数据 invoke Calculate,hWin,WM_COMMAND,IDB_MS,0 .elseif (eax==131 || eax==163) ; o 记忆加 invoke Calculate,hWin,WM_COMMAND,IDB_MPLUS,0 .elseif (eax==132 || eax==164) ; p 记忆减 invoke Calculate,hWin,WM_COMMAND,IDB_MSUB,0 ;------------------------------------------------- .elseif (eax==119 || eax==151) ; c 复制 invoke Calculate,hWin,WM_COMMAND,IDM_COPY,0 .elseif (eax==138 || eax==170) ; v 粘贴 invoke Calculate,hWin,WM_COMMAND,IDM_PASTE,0 .elseif (eax==133 || eax==165) ; q 退出 invoke Calculate,hWin,WM_COMMAND,IDM_EXIT,0 .elseif (eax==155 || eax==123) ; g 分组 invoke Calculate,hWin,WM_COMMAND,IDM_GROUP,0 .elseif (eax==127 || eax==159) ; k 快捷键 invoke Calculate,hWin,WM_COMMAND,IDM_KJJ,0 .elseif (eax==124 || eax==156) ; h 帮助 invoke Calculate,hWin,WM_COMMAND,IDM_HELP,0 .elseif (eax==117 || eax==149) ; a 关于计算器 invoke Calculate,hWin,WM_COMMAND,IDM_ABOUT,0 ;------------------------------------------------- .endif ;--------------------------------------------------------- .elseif uMsg == WM_COMMAND ;按钮消息处理 mov eax,param1 finit ;--------------------------------------------- .if eax==IDB_C ;初始化 invoke Init mov MemoryNeg,0 fldz fstp Memory ;---------------------------------------------- .elseif eax==IDB_CE;清除当前数据 .if IsError==1 || HasEqual==1 invoke Init ret .endif fldz .if Operator=='.' mov IsStart,0 fst Operand1 mov HasNeg1,0 .else fst Operand2 mov HasNeg2,0 .endif fst Temporaryfst Resultfinit mov HasPoint,0 mov HasEqual,0 mov IsError,0 lea esi,Output mov BYTE PTR [esi],'0' mov BYTE PTR [esi+1],0 invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;----------------------------------------------- .elseif eax==IDB_BACK ;退格 .if IsGroup==1 invoke UnGroupNum .endif lea esi,Output .if BYTE PTR [esi+1]==0 mov BYTE PTR [esi],'0' .if Operator=='.' mov IsStart,0 .endif .else .while BYTE PTR [esi]!=0 inc esi .endw mov BYTE PTR [esi-1],0 .endif invoke StrToFloat,addr Output,addr Temporary fld Temporary ;保存操作数 .if Operator=='.' fstp Operand1 .else fstp Operand2 .endif .if IsGroup==1 invoke GroupNum .endif invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;--------------------------------------------- .elseif (eax>=IDB_0) && (eax<=IDB_9) ;数字按键 .if HasEqual==1 fldz fst Operand1 fst Operand2fst Temporaryfst Resultfinitmov IsStart,0 mov HasPoint,0 mov HasEqual,0 mov HasNeg1,0 mov HasNeg2,0 mov ResultNeg,1 mov Operator,'.' mov IsError,0 lea esi,Output mov BYTE PTR [esi],'0' mov BYTE PTR [esi+1],0 .endif invoke NumBtn,eax ;-------------------------------------------- .elseif eax==IDB_POINT;小数点 .if HasEqual==1 invoke Init .endif .if HasPoint==0 lea esi,Output .while BYTE PTR [esi]!=0 inc esi .endw mov BYTE PTR [esi],'.' mov BYTE PTR [esi+1],0 mov HasPoint,1 mov IsStart,1 invoke SavePreData invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output .endif ;------------------------------------------- .elseif eax==IDB_NEG ;取反 invoke AddDelNeg lea esi,Output.if BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0;不加负号的情况 .elseif Operator=='.' xor HasNeg1,1 .elseif Operator!='.' xor HasNeg2,1 .endif invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;------------------------------------------ .elseif (eax>=IDB_DIV) && (eax<=IDB_ADD) ;加减乘除 .if Operator!='.' && HasEqual==0 invoke GetResult .endif .if eax==IDB_DIV mov BYTE PTR Operator,'/' .elseif eax==IDB_MUL mov BYTE PTR Operator,'*' .elseif eax==IDB_SUB mov BYTE PTR Operator,'-' .elseif eax==IDB_ADD mov BYTE PTR Operator,'+' .endif mov HasEqual,0 mov HasPoint,0 fldz fstp Operand2 mov IsStart,1 invoke SendMessage,hTextM,WM_SETTEXT,0,NULL;------在上面文本框显示操作数1-----lea esi,Outputinvoke FloatToStr,Operand1,addr Output.while BYTE PTR [esi]!=0inc esi.endwmov bl,Operatormov [esi],blmov BYTE PTR [esi+1],0.if HasNeg1==1invoke AddDelNeg.endifinvoke SendMessage,hEdit2,WM_SETTEXT,0,addr Output;------在下面文本框显示0------lea esi,Outputmov BYTE PTR [esi],'0'mov BYTE PTR [esi+1],0invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;----------------------------------------- .elseif eax==IDB_EQU ;等于 .if Operator!='.' invoke GetResult .endif ;------------------------------------------ .elseif eax==IDB_PER ;百分号 finit .if Operator=='.' fld Num100 fld Operand1 fdiv ST(0),ST(1) fstp Operand1 invoke FloatToStr,Operand1,addr Output .if HasNeg1==1 invoke AddDelNeg .endif .if IsGroup==1 invoke GroupNum .endif invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output .else ;功能 Op1 + Op2 % = Op1 + Op1*Op2÷100 fld Num100 fld Operand2 fdiv ST(0),ST(1) fstp Operand2 ;Op2÷100=>Op2 ;--------保护操作数1及运算符----- mov bl,Operator mov Buffer,bl ;Operator=>Buffer mov Operator,'*' fld Operand1 fstp Temporary ;Op1=>Temporary mov bh,HasNeg1 ;HasNeg1=>bh ;------------------------------------- invoke GetResult ;Op1*Op2÷100 =>Op1 ;-------运算结果给Op2------- fld Operand1 fstp Operand2 mov bl,HasNeg1 mov HasNeg2,bl ;-------换回Op1和运算符----- fld Temporary fstp Operand1 mov HasNeg1,bh mov bl,Buffer mov Operator,bl invoke GetResult ;最后一步运算 .endif mov HasEqual,1 ;------------------------------------------ .elseif eax==IDB_DAO ;倒数 lea esi,Output mov bx,4000h finit .if Operator=='.' ;只有一个操作数 fld Operand1 ftst fstsw ax and bx,ax jnz dao_error ;Operand1==0 fld1 ;Operand1!=0 fld Operand1 fdiv fst Result fstp Operand1 mov bl,HasNeg1 mov ResultNeg,bl mov HasEqual,1 .else ;已经有操作数1,并且有双目操作符,算操作数2的倒数 fld Operand2 ftst fstsw ax and ax,bx jnz dao_error ;0perand2==0 fld1 ;0perand2!=0 fld Operand2 fdiv ;ST(1) ÷ ST(0) => ST(1),弹出ST fst Result fstp Operand2 mov bl,HasNeg2 mov ResultNeg,bl .endif jmp dao_show dao_error: mov IsError,1 invoke SendMessage,hEdit1,WM_SETTEXT,0,addr DivError mov BYTE PTR[esi],'0' mov BYTE PTR[esi+1],0 ret dao_show: invoke FloatToStr,Result,addr Output .if ResultNeg==1 invoke AddDelNeg .endif lea edi,Output .while BYTE PTR[edi]!=0 ;判断结果是否有小数点 inc edi .if BYTE PTR [edi]=='.' mov HasPoint,1 .endif .endw .if IsGroup==1 invoke GroupNum .endif invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;----------------------------------------------- .elseif eax==IDB_SQRT ;开方 lea esi,Output finit .if Operator=='.' ;只有一个操作数 .if HasNeg1==1 jmp sqrt_error .endif fld Operand1 fsqrt fst Result fst Operand1 mov HasEqual,1 .else ;已经有操作数1,并且有双目操作符,算操作数2的开方 .if HasNeg2==1 jmp sqrt_error .endif fld Operand2 fsqrt fst Result fst Operand2 .endif jmp sqrt_show sqrt_error: mov IsError,1 invoke SendMessage,hEdit1,WM_SETTEXT,0,addr FuncError mov BYTE PTR[esi],'0' mov BYTE PTR[esi+1],0 ret sqrt_show: invoke FloatToStr,Result,addr Output lea edi,Output .while BYTE PTR [edi]!=0 ;判断结果是否有小数点 inc edi .if BYTE PTR [edi]=='.' mov HasPoint,1 .endif .endw .if IsGroup==1 invoke GroupNum .endif invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;------------------------------------------------ .elseif eax==IDB_MC ;清除记忆 fldz fstp Memory mov MemoryNeg,0 invoke SendMessage,hTextM,WM_SETTEXT,0,NULL invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL ;-------------------------------------------------- .elseif eax==IDB_MR ;显示记忆 invoke ShowMemory ;------------------------------------------------ .elseif eax==IDB_MS ;记忆当前数据 .if Operator=='.' || Operator!='.' && HasEqual==1 fld Operand1 mov bl,HasNeg1 .elseif Operator!='.' && HasEqual==0 fld Operand2 mov bl,HasNeg2 .endif fstp Memory mov MemoryNeg,bl mov IsShowMem,0 invoke ShowMemory ;----------------------------------------------- .elseif eax==IDB_MPLUS ;记忆加 invoke MemoryFunc,eax ;------------------------------------------------ .elseif eax==IDB_MSUB ;记忆减 invoke MemoryFunc,eax ;------------------------------------------------ .elseif eax==IDM_COPY ;复制 invoke GlobalAlloc,GMEM_MOVEABLE,35 ;配置一个内存块 mov hGlobal ,eax invoke GlobalLock,hGlobal ;锁定内存块 mov DWORD PTR pGlobal ,eax lea esi,Output mov edi,DWORD PTR pGlobal mov ecx,35 rep movsb ;复制字符串 invoke GlobalUnlock,hGlobal ;解锁内存块 invoke OpenClipboard, NULL ;打开剪切板 invoke EmptyClipboard ;清空剪切板 invoke SetClipboardData,CF_TEXT,hGlobal ;把内存句柄交给剪贴簿 invoke CloseClipboard ;------------------------------------------------ .elseif eax==IDM_PASTE invoke IsClipboardFormatAvailable,CF_TEXT ;确定剪贴簿是否含有CF_TEXT格式的数据 invoke OpenClipboard,NULL ;打开剪切板 invoke GetClipboardData,CF_TEXT ;得到代表文字的内存块代号 mov hGlobal,eax invoke GlobalLock ,hGlobal ;解锁内存块 mov DWORD PTR pGlobal,eax mov ecx,35 lea edi,Output mov esi,eax rep movsb ;复制字符串 invoke GlobalUnlock ,hGlobal ;解锁内存块 invoke CloseClipboard ;关闭剪切板 invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;-------------------------------------------------- .elseif eax==IDM_GROUP ;分组 .if IsGroup==0 invoke CheckMenuItem,hMenu,IDM_GROUP,MF_CHECKED invoke GroupNum .else invoke CheckMenuItem,hMenu,IDM_GROUP,MF_UNCHECKED invoke UnGroupNum .endif xor BYTE PTR IsGroup,1 invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Output ;--------------------------------------------------- .elseif eax==IDM_KJJ ;快捷键帮助 invoke ShellAbout,hWin,addr ProgramName,addr ShortCuts,hIcon ;---------------------------------------------------- .elseif eax==IDM_HELP invoke WinHelp,hWin,addr HelpFile,HELP_CONTENTS,1 ;--------------------------------------------------- .elseif eax==IDM_ABOUT invoke ShellAbout,hWin,addr ProgramName,addr About,hIcon ;---------------------------------------------------.elseif eax==IDM_EXITinvoke Calculate,hWin,WM_CLOSE,param1,param2 .endif ;------------------------------------------------------- .elseif uMsg == WM_CLOSE invoke Shell_NotifyIcon,NIM_DELETE,addr NotifyIcon invoke EndDialog,hWin,NULL invoke PostQuitMessage,0 ;-------------------------------------------------------- .else invoke DefWindowProc,hWin,uMsg,param1,param2 ;默认消息处理 ret .endif ;------------------------------------------------------- invoke SetFocus,hWin mov eax,0 ret Calculate endp;------------------------------------------------------------;------------------------------------------------------------; 初始化所有状态变量和FPU寄存器;------------------------------------------------------------Init procmov IsStart,0mov HasPoint,0mov HasEqual,0mov HasNeg1,0mov HasNeg2,0mov Operator,'.'mov IsError,0 fldz fst Temporaryfst Resultfst Operand1fst Operand2 finitlea esi,Outputmov BYTE PTR [esi],'0'mov BYTE PTR [esi+1],0invoke SendMessage,hEdit1,WM_SETTEXT,0,addr Outputinvoke SendMessage,hEdit2,WM_SETTEXT,0,NULLinvoke SendMessage,hTextM,WM_SETTEXT,0,NULLretInit endp;-----------------------------------------------------------;-----------------------------------------------------------;数字按键消息处理程序 ;把按钮发送的数值eax添加在Output后面,并调用SavePreData保存;------------------------------------------------------------ NumBtn proc USES eax,NUM:DWORD mov eax,NUMsub eax,IDB_0add eax,'0'lea esi,Output.if IsStart==0 mov IsStart,1mov [esi],almov BYTE PTR [esi+1],0.else.if BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0 && al=='0' ; 0 再输入0 ret;-----不添加数字的情况-------- .elseif BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0 && al>='1' && al<='9' ; 0 再输入不为0数字mov [esi],almov BYTE PTR [esi+1],0.else.while BYTE PTR [esi]!=0inc esi.endwmov [esi],almov BYTE PTR [esi+1],0.endif.endifinvoke SavePreDatainvoke SendMessage,hEdit1,WM_SETTEXT,0,addr OutputretNumBtn endp ;-----------------------------------------------------------;-----------------------------------------------------------;保存当前文本框中的数据;如果运算符还没变变化,则当前显示的是操作数1,否则是操作数2;-----------------------------------------------------------SavePreData proc.if IsGroup==1invoke UnGroupNum.endiflea esi,Output.if Operator=='.' ;当前显示的是第一个操作数;------------------------------------.if HasNeg1==1invoke AddDelNeg.endifinvoke StrToFloat,addr Output,addr Operand1.if HasNeg1==1invoke AddDelNeg.endif.else;-------------------------------------.if HasNeg2==1invoke AddDelNeg.endif.if IsGroup==1invoke UnGroupNum.endifinvoke StrToFloat,addr Output,addr Operand2.if HasNeg2==1invoke AddDelNeg.endif.endif;-------------------------------------.if IsGroup==1invoke GroupNum.endifretSavePreData endp;-----------------------------------------------------------;-----------------------------------------------------------;显示存储信息;无论Memory为何值,都在上面的文本框中显示M和Memory数值;再按一次MR,取消显示;------------------------------------------------------------ShowMemory proc .if IsShowMem==0 ;还没有显示invoke SendMessage,hTextM,WM_SETTEXT,0,addr TextM invoke FloatToStr,Memory,addr Output .if MemoryNeg==1 invoke AddDelNeg .endif invoke SendMessage,hEdit2,WM_SETTEXT,0,addr Output mov BYTE PTR IsShowMem,1 .else invoke SendMessage,hTextM,WM_SETTEXT,0,NULL invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL mov BYTE PTR IsShowMem,0 .endifretShowMemory endp;-----------------------------------------------------------;-----------------------------------------------------------;在Output字符串前加上或取消‘-’号;有'-'号,则取消;没有'-'号,则添上;-----------------------------------------------------------AddDelNeg proc USES ebx ecxlea esi,Outputlea edi,Output.if BYTE PTR [esi]=='0' && BYTE PTR [esi+1]==0;----显示‘0’时不加----ret.endif;-----------没有‘-’--加上------------------.if BYTE PTR [esi]!='-' .while BYTE PTR [esi]!=0inc esi.endw.while esi!=edimov bl,[esi]mov [esi+1],bldec esi.endwlea esi,Outputmov bl,[esi]mov [esi+1],blmov BYTE PTR [esi],'-';-----------有了‘-’--删除‘-’号------------.else .while BYTE PTR [esi]!=0mov bl,[esi+1]mov [esi],blinc esi.endw;---------------------------------------------.endifretAddDelNeg endp;-----------------------------------------------------------;-----------------------------------------------------------;计算双目运算结果;两个操作数都是保存的正数,正负号由HasNeg1和HasNeg2保存;先进行绝对值的运算,再由两操作数的正负判定结果正负;------------------------------------------------------------GetResult procUSES eax ebxfinit.if IsStart==1 fld Operand2fld Operand1.if Operator=='.'fst Resultjmp show;++++++++++++++++++++++++++++++++++++++++++.elseif Operator=='+' ;-----------------------------------.if HasNeg1==0 && HasNeg2==0faddmov ResultNeg,0;-----------------------------------.elseif HasNeg1==1 && HasNeg2==0fcom ST(1)jle xiao_deng1 ;小于等于fsub ST(0),ST(1) ;(-2 + 1)mov ResultNeg,1jmp over1xiao_deng1: ;(-1 + 2) (-1 + 1)fsub ST(1),ST(0)fstp Resultmov ResultNeg,0 over1:;-----------------------------------.elseif HasNeg1==0 && HasNeg2==1fcom ST(1)jge da_deng2 fsub ST(1),ST(0) ;(1 + -2)fstp Resultmov ResultNeg,0jmp over2 da_deng2: ;大于等于fsub ;(2 + -1) (1 + -1)mov ResultNeg,1over2:;-----------------------------------.elseif HasNeg1==1 && HasNeg2==1faddmov ResultNeg,1.endif;-----------------------------------------.elseif Operator=='-';-----------------------------------.if HasNeg1==0 && HasNeg2==0fcom ST(1)jge da_deng3 fsub ST(1),ST(0) ;(1 - 2)fstp Resultmov ResultNeg,0da_deng3: ;(1 - 1)(2 - 1)fsub mov ResultNeg,1 over3:;-----------------------------------.elseif HasNeg1==1 && HasNeg2==0faddmov ResultNeg,1;-----------------------------------.elseif HasNeg1==0 && HasNeg2==1faddmov ResultNeg,0;-----------------------------------.elseif HasNeg1==1 && HasNeg2==1fcom ST(1)jle xiao_deng4 fsub ;(-2 - -1)mov ResultNeg,1xiao_deng4:;(-1 - -1)(-1 - -2)fsub ST(1),ST(0)fstp Resultmov ResultNeg,0over4:.endif;**************************************.elseif Operator=='*'fmulmov bl,HasNeg1xor bl,HasNeg2mov ResultNeg,bl;÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷.elseif Operator=='/'mov bx,4000hfld Operand2ftst fstsw ax and bx,ax jz NotZeromov IsError,1invoke SendMessage,hEdit1,WM_SETTEXT,0,addr DivErrorretNotZero:fstp Operand2 fdiv ST(0),ST(1)mov bl,HasNeg1xor bl,HasNeg2mov ResultNeg,bl.endif ;----------------------------------------;-----获得结果------fst Operand1fstp Resultmov bl,ResultNegmov HasNeg1,bl mov HasPoint,0 mov HasEqual,1.endif;--------------显示结果------------------------show:invoke FloatToStr,Result,addr Outputlea edi,Output.while BYTE PTR [edi]!=0inc edi.if BYTE PTR [edi]=='.'mov HasPoint,1.endif.endw.if IsGroup==1invoke GroupNum.endif.if ResultNeg==1invoke AddDelNeg.endifinvoke SendMessage,hEdit1,WM_SETTEXT,0,addr Outputinvoke SendMessage,hEdit2,WM_SETTEXT,0,NULLretGetResult endp;------------------------------------------------------------ ;------------------------------------------------------------;记忆加/记忆减;包括记忆加和记忆减;------------------------------------------------------------MemoryFunc proc USES eax ebx,param:DWORDmov eax,paramfinit;----------当前显示的是第一个操作数---------- .if Operator=='.' fld Memory fld Operand1 fstp Operand2 ;Op1=>Op2 fstp Operand1 ;Memory=>Op1 mov bl,MemoryNeg mov HasNeg1,bl ;Memory的符号给Op1的符号 .if eax==IDB_MPLUS mov BYTE PTR Operator,'+' .elseif eax==IDB_MSUB mov BYTE PTR Operator,'-' .endif invoke GetResult ;Op1+Op2=>Op1 fld Operand1 fstp Memory ;Op1=>Memory mov bl,HasNeg1 mov MemoryNeg,bl ;Op1的符号给Memory mov Operator,'.' mov bl,0 mov IsShowMem,bl invoke ShowMemory ;---------当前显示的是第二个操作数------------- .elseif Operator!='.' ;-----保护运算符和操作数1--------- mov bl,Operator mov Buffer,bl ;Operator=>Buffer fld Operand1 fstp Temporary ;Op1暂存Temporary mov bh,HasNeg1 ;Op1的符号位暂存在BH ;--------------------------------- .if eax==IDB_MPLUS mov BYTE PTR Operator,'+' .elseif eax==IDB_MSUB mov BYTE PTR Operator,'-' .endif fld Memory fstp Operand1 ;Memory=>Op1 mov bl,MemoryNeg mov HasNeg1,bl ;Memory的符号给Opd1的符号 invoke GetResult ;Op2+Memory=>Op1 ;----------------------------------- fld Operand1 fst Operand2 ;记忆运算的结果给Op2和Mempry fstp Memory mov bl,HasNeg1 mov HasNeg2,bl ;运算结果符号位给Op2和Mempry符号位 mov MemoryNeg,bl ;-----换回运算符和操作数1---------- fld Temporary fstp Operand1 mov HasNeg1,bh mov bl,Buffer mov Operator,bl invoke SendMessage,hTextM,WM_SETTEXT,0,NULL invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL ;----------在上面的文本框显示操作数1---------- lea esi,Output invoke FloatToStr,Operand1,addr Output .while BYTE PTR [esi]!=0inc esi .endwmov bl,Operatormov [esi],blmov BYTE PTR [esi+1],0.if HasNeg1==1invoke AddDelNeg.endifinvoke SendMessage,hEdit2,WM_SETTEXT,0,addr Output.endif retMemoryFunc endp;------------------------------------------------------------ ;------------------------------------------------------------;GroupNum函数将输出数据的字符串Output进行数字分组。;它首先获取小数点以前的数字位数并保存在寄存器eax中,然后将;(eax-1)÷3 => eax,即为需要添加的字符‘,’数目,;对于小数点及以后的字符都向后移动eax位,对于小数点以前的字符,;向后移动eax位并用ecx计数,当ecx计数到3时添加字符‘,’;并将ecx设为1且eax减一,重复上述步骤直到eax等于0;-------------------------------------------------------------GroupNum proc USES eax ebx ecx edxlea esi,Outputmov eax,0;----------有小数点---------------------------.if HasPoint==1.while BYTE PTR [esi]!='.'inc eaxinc esi.endw.while BYTE PTR [esi]!=0inc esi.endwdec eaxmov edx,0mov ecx,3div ecx ;得到需要添加‘,’的个数.while BYTE PTR [esi]!='.' ;移动小数点之后的数据mov bx,[esi]mov [esi+eax],bxdec esi.endwmov bx,[esi] ;移动小数点mov [esi+eax],bx;-----------没有小数点--------------------------.elseif HasPoint==0.while BYTE PTR [esi]!=0inc esiinc eax.endwdec eaxmov edx,0mov ecx,3div ecx.endif;-----------------------------------------------dec esimov ecx,0.while eax!=0.if ecx<3mov bx,[esi]mov [esi+eax],bxinc ecx.elsemov BYTE PTR [esi+eax],','dec eaxmov ecx,1.endifdec esi.endwretGroupNum endp;-----------------------------------------------------------;-----------------------------------------------------------;UnGroupNum函数将进行数字分组输出的字符串Output解分组。;它首先获取Output地址存在esi中,然后ecx赋0,并将Output中字符;向前移动ecx个单位,遇见‘,’字符则将ecx加1,直到字符串结束;------------------------------------------------------------UnGroupNum proc USES ebx ecxlea esi,Outputmov ecx,0.while BYTE PTR [esi+ecx]!=0.if BYTE PTR [esi]==','inc ecx.endif mov bx,[esi+ecx] mov [esi],bx inc esi.endwretUnGroupNum endp;----------------------------------------------------------- end start;************************************************************
版权所有
- 汇编语言程序设计——仿win7计算器(功能部分)
- 汇编语言程序设计——仿win7计算器(界面部分)
- 《汇编语言程序设计》——仿windows计算器
- win7计算器功能详解
- win7计算器功能详解
- 新编汇编语言程序设计复习——(1)
- Java Swing实现仿win7计算器
- 仿windows计算器——java版
- 汇编语言程序设计(一)
- 汇编语言程序设计(二)
- 汇编语言程序设计(三)
- 汇编语言程序设计(四)
- 汇编语言程序设计(五)
- 汇编语言程序设计(六)
- 《Windows环境下32位汇编语言程序设计(第2版)》-chapter4-9部分知识点
- 汇编语言程序设计读书笔记(1)
- 汇编语言程序设计读书笔记(2)
- 系统时钟(汇编语言程序设计)
- 程序员的开始
- 解决Heritrix镜像方式存储路径中文乱码的解决方案
- 常用pom.xml中的依赖配置
- 互斥对象锁和临界区锁性能比较
- 动态调整UITableViewCell高度的实现方法
- 汇编语言程序设计——仿win7计算器(功能部分)
- (Java实现)HTML转JPG,TIFF等图片格式和TIFF图片合并功能解决方案。
- POJ-1442-treap
- IBM院士:用DB2 10创建可信信息基础
- Android OpenGL
- 一行代码解决各种IE兼容问题
- 【OSC手机App技术解析】- 应用内Web链接的处理
- vi 使用总汇
- .NET 数据库连接池类 (修改)