⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ewcalc.asm

📁 简易的计算器,能进行加,减,乘,除等简单的运算!
💻 ASM
📖 第 1 页 / 共 5 页
字号:
MulEM   PROC
      .if PT+36 > 0 || R+36 > 0 ; Decimal numbers
           call     ShiftDec
            jmp     Exit
      .endif 
        call     MulMW
      INVOKE     CopyMW, offset R, offset R3, 4
         mov     eax, PT+44
         mov     ebx, R+44
         and     R+44, 0
      .if eax != ebx            ; Minus
            or      R+44, 1
      .endif
        call     BaseToAscii
Exit:
         RET
MulEM   ENDP

;=========================================================================|
;                         Setup for  divide routine.                      |
;=========================================================================|
DivEM   PROC
      .if R > 0 || R+4 > 0 || R+4 > 0 || R+8 > 0 || R+24 > 0
           call     FPDivMW
            jmp     Exit
      .endif
      .if PT+36 > 0 || R+36 > 0
           call     ShiftDec
            jmp     Exit
      .endif
        call     DivMW
      INVOKE     CopyMW, offset R, offset R2, 4
         mov     eax, PT+44
         mov     ebx, R+44
         and     R+44, 0
      .if eax != ebx            ; Minus
            or      R+44, 1
      .endif
        call     BaseToAscii
Exit:
         RET
DivEM   ENDP

;=========================================================================|
;           Rounding or borrowing for decimal add and subtract.           |
;=========================================================================|
Round   PROC
         cmp     BPress, 2
         je      Subem
      INVOKE     lstrlen, ADDR LBuff
         add     eax, 2
      INVOKE     lstrcpyn, ADDR Buff, ADDR ConvI, eax
      INVOKE     lstrcat, ADDR Buff, ADDR RBuff + 1
        call     AsciiToBase
      .if HRBuff > '0' 
            add     R+12, 1
      .endif
        call     BaseToAscii
         jmp     Done
Subem:
      INVOKE     lstrcpy, ADDR Buff, ADDR HLBuff
      INVOKE     lstrcat, ADDR Buff, ADDR Period
      INVOKE     lstrcat, ADDR Buff, ADDR One
      INVOKE     lstrcat, ADDR Buff, ADDR HRBuff
        call     AsciiToBase
         sub     R+12, 1

      INVOKE     lstrcpy, ADDR Buff, ADDR LBuff
      INVOKE     lstrcat, ADDR Buff, ADDR Period
      INVOKE     lstrcat, ADDR Buff, ADDR Zero
      INVOKE     lstrcat, ADDR Buff, ADDR RBuff
      INVOKE     CopyMW, offset PT, offset R, 12
        call     AsciiToBase
        push     R5+32
        call     Prep
         pop     R5+32
Done:   
         RET
Round   ENDP

;=========================================================================|
;   Converts ascii string of Dec, Hex, Oct or Bin to a 128 bit num value. |
;=========================================================================|
AsciiToBase PROC
         and     DP, 0   
         and     Pos, 0
         and     cnt, 0
      INVOKE     CLRMW, offset R, 32
      INVOKE     lstrlen, ADDR Buff
      .if sw1 == 19 && eax > 19 && BPress == 3  ; Limit Multiplicand & Multiplier to 19
            mov     edx, offset Buff
            add     edx, 18
         .if byte ptr [edx]+1 >= 35h
               inc     byte ptr [edx]+0 ; + 1
         .endif
            mov     byte ptr [edx]+1, 0
            sub     eax, 19
            mov     Work, eax
      .endif
      INVOKE     lstrlen, ADDR Buff
         mov     ecx, offset Buff
         xor     edx, edx

      .while (eax)
      .if byte ptr [ecx] > 60h
            sub     byte ptr [ecx], 57h
            and     Pos, 0
      .elseif byte ptr [ecx] > 40h
            sub     byte ptr [ecx], 37h
            and     Pos, 0
      .elseif byte ptr [ecx] == 2eh
            or      Pos, 1
            or      cnt, 1
            or      DP, 1
;******* Reduce decimal numbers to 19  ;16
           push     eax
           push     ecx
           push     edx
         INVOKE     lstrlen, ADDR Buff
            mov     ebx, offset Buff
            add     ebx, edx
            sub     eax, edx
         .if eax > 19
            .if byte ptr [ebx]+20 >= 35h
                  inc     byte ptr [ebx]+19 ; + 1
            .endif
               mov     byte ptr [ebx]+20, 0 ; Terminate string
         .endif
            pop     edx
            pop     ecx
            pop     eax
;*******
      .elseif byte ptr [ecx] == 2dh
            or      R+44, 1                 ; Minus
      .else
            xor     byte ptr [ecx], 30h
         .if  byte ptr [ecx] == 0h && Pos == 1
               add     R+40, 1              ; Number of leading zeros after decimal
         .else
               and     Pos, 0
         .endif   
      .endif
         inc     ecx
         inc     edx 
      .if cnt == 0
            mov     R+32, edx               ; Number of whole numbers
      .endif
         cmp     edx, 32 ;64                    ; 32 !!!!!!!!!!!!!!!!!!
         jnb     done
         dec     eax
      .endw
done:
      .if edx == 0 || edx == 1 && R+44 == 1 
            inc     edx
      .endif
       MOVmd     HBase, Base
         mov     edi, offset Buff           ; edi points to string to copy
         mov     R3+12, 1
         mov     R4+12, 1
         add     edi, edx
         dec     edi
         and     cnt, 0
      .if R+44 == 1
            dec     edx
            sub     R+32, 1
      .endif 
Conv:
      .if byte ptr[edi] == 2eh
          MOVmd     D+32, R+32              ; Number of whole numbers
          MOVmd     D+36, cnt               ; Number of decimal numbers
          MOVmd     D+40, R+40              ; Number of leading zeros after decimal
          MOVmd     D+44, R+44              ; Minus
         INVOKE     CopyMW, offset D+16, offset R, 4
         INVOKE     CLRMW, offset R, 32  
         INVOKE     CopyMW, offset R+16, offset D+16, 8
            mov     R3+12, 1
            mov     R4+12, 1
            jmp     PastDec
      .endif
         add     cnt, 1
         mov     al, byte ptr[edi]          ; Move byte edi points to into al
         and     eax, 000000ffh

      INVOKE     CLRMW, offset B, 4  
         mov     B+12, eax
      INVOKE     CopyMW, offset A, offset R4, 4
        call     MulMW

      INVOKE     CopyMW, offset A, offset R, 4
      INVOKE     CopyMW, offset B, offset R3, 4
         or      PassDec, 1
        call     AddMW
         and     PassDec, 0

      INVOKE     CopyMW, offset A, offset R4, 4
      INVOKE     CLRMW, offset B, 4  
       MOVmd     B+12, Base
        call     MulMW
      INVOKE     CopyMW, offset R4, offset R3, 4
PastDec:
         dec     edi
         dec     edx
         jnz     Conv
         RET
AsciiToBase ENDP

;=========================================================================|
;   Converts a 128 bit num value to a Dec, Hex, Oct or Bin ascii string.  |
;=========================================================================|
BaseToAscii PROC
         mov     DecPos, 0
        push     Base
        push     esi
      .if sw2 != 0
          MOVmd     Base, sw2
      .endif
         mov     Pos, 0
      .if R+28 > 0
         INVOKE     CopyMW, offset A, offset R+16, 4
            mov     Pos, 1
      .else
         INVOKE     CopyMW, offset A, offset R, 4
      .endif
       MOVmd     B+12, Base
         xor     edi, edi
         xor     esi, esi

Loop1:
         or      R5+24, 1
        call     DivMW
         and     R5+24, 0
      INVOKE     CopyMW, offset A, offset R2, 4
      .if dl > 9h
            add     dl,37h         ; Convert to hex ASCII
      .else
            add     dl,30h         ; Convert to dec ASCII
      .endif
         mov     Buff[esi], dl
         inc     edi
      .if A+12 > 0 || A+8 > 0 || A+4 > 0 || A > 0
            inc     esi
            jmp     Loop1
      .endif
      .if R+28 > 0 && Pos == 1     ; Decimal portion
            inc     esi
            mov     eax, R+40
            inc     eax
           push     edi
           push     esi
         INVOKE     lstrcpyn, ADDR Buff[esi], ADDR Zeros, eax  ; Number of leading zeros after dec
            pop     esi
            pop     edi
            add     edi, R+40
            add     esi, R+40
            mov     byte ptr Buff[esi], 2eh
            mov     DecPos, esi
            inc     edi
            inc     esi
         INVOKE     CopyMW, offset A, offset R, 4
            mov     Pos, 0
            jmp     Loop1
      .endif
         xor     ecx, ecx
      .if R+44 == 1                ; Minus
            mov     byte ptr ConvI, 2dh
            inc     ecx
      .endif
Loop2:
         mov     al, byte ptr Buff[esi]
         mov     byte ptr ConvI[ecx], al
         inc     ecx
         dec     esi
         dec     edi
         jnz     Loop2
         mov     byte ptr ConvI[ecx], 0h

         mov     eax, Base
      .if eax == HBase
            mov     RBuff, 0h
         INVOKE     lstrlen, ADDR ConvI
            mov     esi, offset ConvI
            mov     edi, offset LBuff
Loop3:
         .if byte ptr[esi] == 2eh
               mov     byte ptr[edi], 0h
               mov     edi, offset RBuff
               inc     esi
               dec     eax
               jz      AllDone
         .endif    
            mov     bl, byte ptr[esi]
            mov     byte ptr[edi], bl
            inc     edi
            inc     esi
            dec     eax
            jnz     Loop3
            mov     byte ptr[edi], 0h
      .endif
AllDone:
      .if cpy != 8
         INVOKE     lstrcpy, ADDR ConvO, ADDR ConvI
      .endif
         pop     esi
         pop     Base
          RET
BaseToAscii ENDP

;=========================================================================|
;                        Clears multiple dwords.                          |
;=========================================================================|
CLRMW   PROC  To: DWORD, Num: DWORD
      pushad
         xor     eax, eax
         mov     ebx, To
         mov     ecx, Num
Loop1:   mov     dword ptr[ebx+eax], 0
         add     eax, 4
        loop     Loop1
       popad
         RET
CLRMW   ENDP

;=========================================================================|
;                        Copies multiple dwords.                          |
;=========================================================================|
CopyMW  PROC  To: DWORD, From: DWORD, Num: DWORD
      pushad
         xor     eax, eax
         mov     edx, To
         mov     ebx, From
         mov     ecx, Num
Loop1:
        push     dword ptr[ebx+eax]
         pop     dword ptr[edx+eax]
         add     eax, 4
        loop     Loop1
       popad
         RET
CopyMW  ENDP

;=========================================================================|
;                       Compares multiple dwords.                         |
;=========================================================================|
CompMW  PROC  Left: DWORD, Right: DWORD, Num: DWORD
      pushad
         xor     eax, eax
         mov     Work, 0
         mov     ebx, Left
         mov     edx, Right
         mov     ecx, Num
Loop1:
         mov     esi, dword ptr[ebx+eax]
      .if esi > dword ptr[edx+eax]
            or      Work, 1              ; A > B 
            jmp     Done
      .endif
      .if esi < dword ptr[edx+eax]
            or      Work, 2              ; A < B
            jmp     D

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -