Full console input and output added:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; asciiadder :: takes two unsigned ascii decimal strings and adds them ;;
;; designed to add very long numbers. Surely an easier way, but it was fun. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; build with console assemble and link ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include \masm32\include\masm32rt.inc
asciiadder PROTO :DWORD, :DWORD, :DWORD
zinput MACRO prompt:VARARG
LOCAL txt
LOCAL buffer
IFNB <prompt>
.data
txt db prompt, 0
align 4
.data?
buffer db 2052 dup (?)
align 4
.code
invoke StdOut,ADDR txt
invoke StdIn,ADDR buffer,2048
mov BYTE PTR [buffer+eax], 0
invoke StripLF,ADDR buffer
EXITM <OFFSET buffer>
ELSE
.data?
buffer db 2052 dup (?)
align 4
.code
invoke StdIn,ADDR buffer,2048
mov BYTE PTR [buffer+eax], 0
invoke StripLF,ADDR buffer
EXITM <OFFSET buffer>
ENDIF
ENDM
.data
align 4
; asciinumber1 db 2048 dup (0)
lpstring1 dd 0
align 4
; asciinumber2 db 2048 dup (0)
lpstring2 dd 0
align 4
asciidest db 2048 dup (0)
db 4 dup (0)
.code
start:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; get first number from user input ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print "enter first number - 2048 digits max", 13, 10
mov lpstring1, zinput()
invoke locate,0,4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; get second number from user input ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print "enter second number - 2048 digits max", 13, 10
mov lpstring2, zinput()
invoke locate,0,8
cls ; clear the screen to get the inputting outta the way
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; print full equation ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
print lpstring1, 13, 10, 13, 10
print chr$("plus"), 13, 10, 13, 10
print lpstring2, 13, 10, 13, 10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; perform the addition ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
invoke asciiadder, lpstring1, lpstring2, addr asciidest
;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; print the results ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;
print chr$("equals"), 13, 10, 13, 10
print offset asciidest, 13, 10
inkey
exit
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 16
nops 13
asciiadder proc src1:dword, src2:dword, dst:dword
push ebp
push ebx
push esi
push edi
mov esi, [esp+14h]
mov ebp, [esp+18h]
mov edi, [esp+1Ch]
xor ecx, ecx
@@:
cmp byte ptr [esi+ecx+1], 0 ; get the last ascii byte
jz @f
inc ecx
jmp @b
@@:
xor ebx, ebx
@@:
cmp byte ptr [ebp+ebx+1], 0 ; get the last ascii byte
jz @f
inc ebx
jmp @b
@@:
cmp ecx, ebx ; effectively right aligning all strings - then work our way left
jl ebxgr
mov edx, ecx
jmp setdst
ebxgr:
mov edx, ebx
setdst:
inc edx ; add an extra byte for potential carry
calc:
mov al, 0
cmp ecx, -1
js @f
mov al, byte ptr [esi+ecx]
@@:
cmp ebx, -1
js @f
add al, byte ptr [ebp+ebx]
@@:
sub al, 30h
cmp al, 0Fh
jl @f
sub al, 30h
@@:
cmp al, 0Ah
jl @f
sub al, 0Ah
inc byte ptr [edi+edx-1]
@@:
add al, 30h
add al, byte ptr [edi+edx]
cmp al, 39h
jng @f
sub al, 0Ah
inc byte ptr [edi+edx-1]
@@:
mov byte ptr [edi+edx], al
dec ebx
dec ecx
dec edx
jnz calc
cmp byte ptr [edi+edx], 30h ; test to see if first byte in dest is the carry byte
jg @f
add byte ptr [edi], 30h ; if so, convert to ascii
@@:
pop edi
pop esi
pop ebx
pop ebp
ret 12
asciiadder endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
end start
Still trying to make the routine a bit faster....
But for demonstration purposes, it is fine as is, I suppose.
Using modified 'input()' macro, allowing up to 2048 digit input
72687256878728728578278273764572634567527634762347624623645268275497274697367264
59726597629769726979767654976479567269726957629764592769247629767629347697676576
876587872876575764578568745687564758756
plus
10101010101010101010101010101010101010101010101010101010101010101010101010101010
10101010101100110101010101010010100101001010101001010010100100101010010100101001
010100101001010010100101001010010100101001010010010100100101
equals
01010101010101010101017369735788882973867928837477467364466853773577244863472465
53692855982856984682746982760763986982798077775597748957736982705863977469287024
8639867730348707686676977588882886675865579578755697664858857