📄 ewcalc.asm
字号:
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 + -