卓越2008

用一颗谦虚的心面对大家,用一颗坚定的心面对困难,用一颗执著的心面对理想,用一颗虔诚的心面对技术。

导航

无聊~写个计算器...待续

Posted on 2007-08-07 21:13  Casm  阅读(321)  评论(0)    收藏  举报

 

  1.386
  2.model flat, stdcall
  3
  4include PublicMethod.inc
  5
  6.code
  7
  8IndexOfChar proc  lpString : DWORD, findChar : BYTE    ;查找某字符在字符串中第一次出现的位置,返回-1表示不存在
  9    
 10    push    ebx
 11    push    esi
 12    push    ecx
 13    
 14    mov    eax,    -1
 15    mov    ebx,    lpString
 16    xor    esi,    esi
 17    
 18    @@:
 19    mov    cl,    [ebx + esi]
 20    cmp    cl,    0
 21    je    @F
 22    
 23    cmp    al,    findChar
 24    inc    esi
 25    jne    @B
 26    dec    esi
 27    mov    eax,    esi
 28    
 29    @@:    
 30    pop    ecx
 31    pop    esi
 32    pop    ebx
 33
 34    ret
 35
 36IndexOfChar endp
 37
 38InsertCharToIndex proc lpString : DWORD, index : DWORD, char : BYTE    ;在字符串的index处插入字符,返回0表示插入错误,正确插入则返回值是无效值
 39    
 40    push    ecx
 41    push    ebx
 42    push    esi
 43    
 44    mov    eax,    index
 45    mov    ecx,    sizeof lpString
 46    
 47    cmp    eax,    ecx    ;判断插入位置是否合理
 48    jg    @ERROR
 49    cmp    eax,    0
 50    jl    @ERROR
 51    
 52    mov    edx,    index
 53    invoke    StringLength,     lpString
 54    mov    esi,    eax
 55    
 56    @NEXT:            ;依次把index后字符移动一位
 57    mov    ebx,    lpString
 58    cmp    esi,    edx    
 59    jl    @INSERT
 60    mov    al,    [ebx + esi]
 61    mov    [ebx + esi + 1],    al
 62    dec    esi
 63    jmp    @NEXT
 64    
 65    @ERROR:
 66    xor    eax,    eax
 67    jmp    @END
 68    
 69    @INSERT:
 70    inc    esi
 71    mov    al,    char
 72    mov    [ebx + esi],    al
 73    
 74    @END:
 75    ;应该在此处添加一个结束符号
 76    pop    esi
 77    pop    ebx
 78    pop    ecx
 79    ret
 80
 81InsertCharToIndex endp
 82
 83StringLength proc lpString : DWORD    ;返回字符串的长度
 84
 85    push    esi
 86    push    ebx
 87    
 88    xor    esi,    esi
 89    mov    ebx,    lpString
 90    
 91    @NEXT:
 92    mov    al,    [ebx + esi]
 93    cmp    al,    0
 94    je    @F
 95    inc    esi
 96    jmp    @NEXT
 97    
 98    @@:
 99    mov    eax,    esi
100    
101    pop    ebx
102    pop    esi
103    
104    ret
105    
106StringLength endp
107
108RemoveCharFromString proc lpString : DWORD, index : DWORD    ;删除字符串中某个位置的字符,返回0表示表示未删除成功,返回1表示删除成功
109    
110    push    ecx
111    push    ebx
112    push    esi
113    
114    mov    eax,    index
115    mov    ecx,    sizeof lpString
116    dec    ecx
117    
118    cmp    eax,    ecx    ;判断删除位置是否合理
119    jg    @ERROR
120    cmp    eax,    0
121    jl    @ERROR
122    invoke StringLength, lpString
123    cmp    eax,    0    ;如果字符串为空
124    je    @ERROR
125        
126    mov    ebx,    lpString
127    xor    esi,    esi
128    
129    @NEXT:
130    mov    al,    [ebx + esi + 1]
131    cmp    al,    0
132    je    @RIGHT
133    mov    [ebx + esi], al
134    inc    esi
135    jmp    @NEXT
136    
137    @ERROR:
138    xor    eax,    eax
139    jmp    @END
140    
141    @RIGHT:            ;删除成功
142    xor    al,    al
143    mov    [ebx + esi],    al
144    mov    eax,    1
145    
146    @END:
147    pop    esi
148    pop    ebx
149    pop    ecx
150    
151    ret
152
153RemoveCharFromString endp
154
155GetTrueNum proc lpNum : DWORD    ;把字符串转换成ptNUM结构,返回0代表转换错误
156    local tempNum : ptNUM
157
158    push    ebx
159    push    esi
160    push    edi
161
162    ;获得符号
163    mov    ebx,    lpNum
164    xor    esi,    esi
165    mov    ecx,    sizeof lpNum
166    cmp    ecx,    0
167    je    @ERROR
168    mov    al,    [ebx + esi]
169    cmp    al,    2Dh
170    jne    @GetInterger
171    mov    eax,    1
172    mov    tempNum.numFlag,    eax    ;有符号数
173    inc    esi
174    
175    @GetInterger:
176    ;获得整数部分
177    xor    edi,    edi
178    @NEXT1:
179    mov    al,    [ebx + esi]
180    inc    esi
181    cmp    al,    2Eh    ;如果为小数点则准备取小数部分
182    je    @GetFloat
183    cmp    al,    0
184    je    @END
185    push    ebx        ;取整数部分
186    lea    ebx,    tempNum.integer
187    mov    [ebx + edi],    al
188    pop    ebx
189    inc    edi
190    jmp    @NEXT1
191    
192    @GetFloat:
193    ;获得小数部分
194    xor    edi,    edi
195    @NEXT2:
196    mov    al,    [ebx + esi]
197    inc    esi
198    cmp    al,    0
199    je    @END
200    push    ebx        ;取小数部分
201    lea    ebx,    tempNum.float
202    mov    [ebx + edi],    al
203    pop    ebx
204    inc    edi
205    jmp    @NEXT1
206    
207    
208    @ERROR:
209    xor    eax,    eax
210    jmp    @RET
211    
212    @END:
213    lea    eax,    tempNum
214    
215    @RET:
216     pop ecx
               pop edi
               pop esi
               pop ebx
217     ret
218
219GetTrueNum endp
220
221End

  1.386
  2.model flat, stdcall  ;32 bit memory model
  3option casemap :none  ;case sensitive
  4
  5include Calculator.inc
  6
  7.code
  8
  9start:
 10
 11    invoke GetModuleHandle, NULL
 12    mov    hInstance,    eax
 13
 14    invoke DialogBoxParam, hInstance, DLG_MAIN, NULL, addr DlgProc, NULL
 15    invoke ExitProcess, 0
 16
 17
 18DlgProc proc hWin : HWND, uMsg : UINT, wParam : WPARAM, lParam : LPARAM
 19
 20    mov    eax,    uMsg
 21    .if eax == WM_INITDIALOG
 22
 23        mov    eax,    hWin
 24        xchg    eax,    hWnd
 25        
 26        xor    eax,    eax        
 27        mov    calculatorState,    eax     ;初始化计算器状态,0为初始,1为可输入,2为计算后
 28        mov    pointNum,    eax        ;初始化数值类别0为整数,1位小数
 29        
 30        invoke GetDlgItem, hWin, IDC_TEXTSCREEN
 31        .if eax
 32            
 33            mov    hTextScreen,    eax    
 34            
 35        .endif
 36
 37    .elseif eax == WM_COMMAND
 38    
 39        mov    eax,    wParam
 40        movzx    eax,    ax
 41        invoke SetTextScreen, eax
 42
 43    .elseif eax == WM_CLOSE
 44    
 45        invoke EndDialog, hWin, 0
 46        
 47    .else
 48    
 49        mov    eax,    FALSE
 50        ret
 51        
 52    .endif
 53    mov    eax,    TRUE
 54    ret
 55
 56DlgProc endp
 57
 58
 59
 60Calculate proc firstNum : DWORD, optType : DWORD, secondNum : DWORD
 61
 62    .if optType == IDC_BTN_ADD
 63        
 64        invoke AddOpration, firstNum, secondNum
 65    
 66    .elseif optType == IDC_BTN_SUB
 67    
 68        invoke SubOpration, firstNum, secondNum
 69    
 70    .elseif optType == IDC_BTN_MUL
 71    
 72        invoke MulOpration, firstNum, secondNum
 73    
 74    .elseif optType == IDC_BTN_DIV
 75    
 76        invoke DivOpration, firstNum, secondNum
 77    
 78    .endif
 79    
 80    ret 
 81
 82Calculate endp
 83
 84DivOpration proc firstNum : DWORD, secondNum : DWORD
 85    local    fNum : ptr ptNUM 
 86    local    sNum : ptr ptNUM 
 87
 88    invoke GetTrueNum, firstNum
 89    mov    fNum,    eax
 90    invoke GetTrueNum, secondNum
 91    mov    sNum,    eax
 92    
 93    .if 
 94    
 95    ret
 96
 97DivOpration endp
 98
 99MulOpration proc firstNum : DWORD, secondNum : DWORD
100
101    
102
103MulOpration endp
104
105SubOpration proc firstNum : DWORD, secondNum : DWORD
106
107    
108
109SubOpration endp
110
111AddOpration proc firstNum : DWORD, secondNum : DWORD
112
113    
114
115AddOpration endp
116
117SetTextScreen proc inputOpr : DWORD    ;显示控制
118    local    @screenTextBuffer[40] : BYTE
119    local    @inputNum : BYTE 
120    local    @flag : DWORD    
121    
122    pushad
123    
124    xor    eax,    eax
125    mov    @flag,    eax
126    mov    eax,    inputOpr
127    .if ax >= 48 && ax <= 57        ;当输入为数字的时候
128        
129        lea    ebx,    @inputNum
130        mov    [ebx],    ax    
131        invoke GetDlgItem, hWnd, IDC_TEXTSCREEN
132        mov    hTextScreen,    eax
133        invoke GetWindowText, hTextScreen, addr @screenTextBuffer, sizeof @screenTextBuffer
134        invoke GetWindowTextLength, hTextScreen
135        
136        .if eax < 39
137        
138            lea    ebx,    @screenTextBuffer        ;把新输入的数字加入显示框中
139            xor    esi,    esi
140            
141            mov    eax,    calculatorState
142            
143            .if eax == 0    ;如果为初始化状态
144            
145                .if @inputNum != 48    ;如果输入不为0则改变初始化状态为可输入状态
146                    
147                    inc    eax
148                    mov    calculatorState,    eax                    
149                    
150                .endif
151                jmp    OVER
152                
153            .elseif pointNum == 1    ;如果为小数输入状态,则把数字直接添加到后面
154                
155                invoke GetWindowTextLength, hTextScreen
156                mov    esi,    eax
157                mov    al,    @inputNum
158                mov    [ebx + esi],    al
159                xor    al,    al
160                mov    [ebx + esi + 1],    al
161                jmp    @SETTEXT
162                
163            .elseif eax == 1    ;如果为可输入状态
164            
165                NEXT:
166                mov    al,    [ebx + esi]
167                cmp    al,    0            ;如果到了末尾则加入
168                je    OVER
169                cmp    al,    2Eh            
170                jne    @F
171                inc    @flag                ;如果是小数点则把@flag改为1
172                @@:
173                inc    esi
174                jmp    NEXT
175            
176                OVER:
177                mov    al,    [ebx + esi - 1]
178                cmp    al,    2Eh
179                jne    @F
180                dec    esi
181                dec    @flag
182                
183                @@:    
184                mov    al,    @inputNum
185                mov    [ebx + esi],    al
186                cmp    @flag,    1            ;如果存在小数点,则不在末尾另加小数点
187                je    @F
188            
189                inc    esi
190                mov    al,    2Eh
191                mov    [ebx + esi],    al
192            
193                @@:
194                inc    esi
195                xor    al,    al
196                mov    [ebx + esi],    al
197                
198                @SETTEXT:
199            
200                invoke SetWindowText, hTextScreen, addr @screenTextBuffer
201                
202            .endif
203        
204        .endif
205    
206    .elseif ax == IDC_BTN_CE || ax == IDC_BTN_C    ;清0
207        
208        invoke GetDlgItem, hWnd, IDC_TEXTSCREEN
209        mov    hTextScreen,    eax
210        invoke SetWindowText, hTextScreen, offset szInit
211        xor    eax,    eax
212        mov    calculatorState,    eax    ;初始化状态
213        mov    pointNum,    eax    
214        lea    ebx,    firstNumber        
215        mov    [ebx],     al    
216        lea    ebx,    secondNumber
217        mov    [ebx],    al    
218        
219    .elseif ax == IDC_BTN_BACKSAPCE    ;退格
220    
221        invoke GetDlgItem, hWnd, IDC_TEXTSCREEN
222        mov    hTextScreen,    eax
223        invoke GetWindowText, hTextScreen, addr @screenTextBuffer, sizeof @screenTextBuffer
224        invoke GetWindowTextLength, hTextScreen
225        mov    esi,    eax
226        .if eax == 2
227            
228            xor    eax,    eax
229            mov    calculatorState,    eax
230            mov    pointNum,    eax
231            invoke SetWindowText, hTextScreen, offset szInit
232            
233        .else
234            dec    esi
235            lea    ebx,    @screenTextBuffer
236            mov    al,    [ebx + esi]
237            cmp    al,    2Eh            
238            je    @F                    ;如果最后一个为小数点
239            xor    al,    al
240            mov    [ebx + esi],    al
241            jmp    @END
242            @@:
243            xor    al,    al
244            mov    [ebx + esi],    al
245            dec    esi
246            mov    al,    2Eh
247            mov    [ebx + esi],    al
248            @END:
249            invoke SetWindowText, hTextScreen, addr @screenTextBuffer            
250                        
251        .endif
252    
253    .elseif ax == IDC_BTN_POINT    ;如果输入为小数点
254        
255        invoke GetWindowText, hTextScreen, addr @screenTextBuffer, sizeof @screenTextBuffer
256        invoke GetWindowTextLength, hTextScreen
257        mov    esi,    eax
258        dec    esi
259        lea    ebx,    @screenTextBuffer
260        
261        mov    al,    [ebx + esi]
262        cmp    al,    2Eh    ;判断最后一个字符是否'.'
263        jne    @F        ;如果不是则不做任何处理
264        mov    eax,    1
265        mov    calculatorState,    eax
266        mov    pointNum,    eax    ;如果最后一个字符是'.',数值状态改变为小数
267        @@:            ;如果最后一位不是小数点则说明该数已经是小数
268        
269    .elseif ax == IDC_BTN_FLAG
270    
271        invoke GetWindowText, hTextScreen, addr @screenTextBuffer, sizeof @screenTextBuffer
272        .if calculatorState == 1 ;在可输入状态下
273        
274            lea    ebx,    @screenTextBuffer
275            mov    al,    [ebx]
276            .if al == 2Dh
277            
278                invoke RemoveCharFromString, addr @screenTextBuffer, 0
279                
280            .else
281                
282                invoke InsertCharToIndex, addr @screenTextBuffer, 0, flag
283            
284            .endif
285            
286        .endif
287        
288        invoke SetWindowText, hTextScreen, addr @screenTextBuffer
289        
290    .elseif ax == IDC_BTN_ADD || ax == IDC_BTN_SUB || ax == IDC_BTN_MUL || ax == IDC_BTN_DIV ;四则运算符
291        
292        push    eax
293        invoke StringLength, offset firstNumber
294        .if eax != 0        ;如果第一个数不为空
295            
296            invoke GetWindowText, hTextScreen, offset secondNumber, sizeof secondNumber
297            ;invoke Calculate, firstNumber, operation, secondNumber    ;运算    
298            invoke MessageBox, hWnd , offset firstNumber, offset secondNumber, MB_OK
299            ;把字符串转换为数字mov    firstNumber,    eax
300            pop    operation
301            
302                
303        .else
304            
305            pop    operation        ;记录下运算符
306            invoke GetWindowText, hTextScreen, offset firstNumber, sizeof firstNumber    
307            
308        .endif
309        
310        xor    eax,    eax        
311        mov    calculatorState,    eax     ;初始化计算器状态,0为初始,1为可输入,2为计算后
312        mov    pointNum,    eax        ;初始化数值类别0为整数,1位小数
313                
314    .endif
315    
316    popad
317    ret
318
319SetTextScreen endp
320
321end start
322
323
324
325
326
327