Skip to content

Instantly share code, notes, and snippets.

@abdullahnaseer
Last active May 7, 2018 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abdullahnaseer/1322063d6c1a6de6ea6b7870b962e0ad to your computer and use it in GitHub Desktop.
Save abdullahnaseer/1322063d6c1a6de6ea6b7870b962e0ad to your computer and use it in GitHub Desktop.
String digits multiplication in MASM
.386
.model flat, stdcall
.stack 1024
GetStdHandle PROTO, ; get standard handle
nStdHandle:DWORD ; type of console handle
;Returns: (HANDLE) EAX = A handle to the specified device,
; or INVALID_HANDLE_VALUE flag if function fails.
ReadConsoleA PROTO,
handle:DWORD, ; input handle
lpBuffer:PTR BYTE, ; pointer to buffer
nNumberOfCharsToRead:DWORD, ; number of chars to read
lpNumberOfCharsRead:PTR DWORD, ; number of chars read
lpReserved:PTR DWORD ; 0 (not used - reserved)
; Returns: (BOOL) EAX = TRUE (non-zero) if successful,
; FALSE (zero) if fails.
WriteConsoleA PROTO, ; write a buffer to the console
handle:DWORD, ; output handle
lpBuffer:PTR BYTE, ; pointer to buffer
nNumberOfCharsToWrite:DWORD, ; size of buffer
lpNumberOfCharsWritten:PTR DWORD, ; number of chars written
lpReserved:PTR DWORD ; 0 (not used)
;Returns: (BOOL) EAX = TRUE (non-zero) if successful,
; FALSE (zero) if fails.
ExitProcess PROTO, ; exit program
dwExitCode:DWORD ; return code
;Returns: (VOID)
.data
msg1 byte "Please enter x1: ", 0
msg2 byte "Please enter x2: ", 0
msg3 byte "x1 * x2 = "
inputString1 byte 100 dup(?)
inputString2 byte 100 dup(?)
temp byte 200 dup(?), 0
outputData byte 200 dup(?), 0
count DWORD ?
.code
main proc
;; Display input message
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset msg1, lengthof msg1, offset count, 0
;; Read input message
invoke GetStdHandle, -10 ; Input handle
invoke ReadConsoleA, eax, offset inputString1, lengthof inputString1, offset count, 0
push offset inputString1
sub count, 2
push count
;; Display input message
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset msg2, lengthof msg2, offset count, 0
;; Read input message
invoke GetStdHandle, -10 ; Input handle
invoke ReadConsoleA, eax, offset inputString2, lengthof inputString2, offset count, 0
push offset inputString2
sub count, 2
push count
call multiply
add esp, 16
;; Display output message
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset msg3, lengthof msg3, offset count, 0
;; Display output data
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset outputData, lengthof outputData, offset count, 0
mov eax, 0
invoke ExitProcess, 0
main endp
;; @param offset x1
;; @param count x1
;; @param offset x2
;; @param count x2
;; @return outputData
multiply proc uses eax ebx ecx edx esi edi ebp
mov eax, 0
mov ebx, 0
mov ecx, [esp+36]
mov edx, [esp+44]
mov esi, [esp+32] ; i loop1
dec esi
lloop1:
cmp esi, 0
jl lendloop1
mov ebp, [esp+32]
sub ebp, esi
dec ebp
mov bl, 0 ;; carry
mov edi, [esp+40] ; j loop2
dec edi
lloop2:
cmp edi, 0
jl lendloop2
mov al, [edx+edi]
mov ah, [ecx+esi]
sub al, '0'
sub ah, '0'
mul ah
mov bh, 0
add ax, bx
mov bh, 10
div bh
;add ah, '0'
mov temp[ebp], ah
mov bl, al
dec edi
inc ebp
jmp lloop2
lendloop2:
mov temp[ebp], bl
call addOutputTemp
dec esi
jmp lloop1
lendloop1:
call intToStringConversion
call reverseString
ret
multiply endp
;; @param byte 200 outputData
;; @param byte 200 temp
;; @return outputData + temp
addOutputTemp proc uses eax ebx ecx edx
mov dx, 0 ;; carry
mov ecx, 0
mov ebp, 0
laddloop:
cmp ecx, sizeof outputdata
je lendaddloop
movzx ax, temp[ecx]
movzx bx, outputdata[ecx]
add ax, bx
add ax, dx
mov bh, 10
div bh
mov dl, al
mov outputdata[ecx], ah
inc ecx
jmp laddloop
lendaddloop:
mov outputdata[ecx], dl
call clearTemp
ret
addOutputTemp endp
;; @param byte 200 outputData
;; @return outputData
intToStringConversion proc uses eax ebx ecx edx
mov al, 0 ;; check (treat as boolean)
mov ecx, sizeof outputData
dec ecx
lloop3:
cmp ecx, 0
jl lendloop3
cmp al, 1
je lalreadyChecked
cmp outputData[ecx], 0
je updateCheckEnd
updateCheck:
mov al, 1
updateCheckEnd:
cmp al, 1
jne lignore
lalreadyChecked:
add outputData[ecx], '0'
lignore:
dec ecx
jmp lloop3
lendloop3:
ret
intToStringConversion endp
;; @param byte 200 temp
;; @return (reset temp)
clearTemp proc uses ecx
mov ecx, sizeof temp
lclearTempLoop:
mov temp[ecx - 1], 0
loop lclearTempLoop
ret
clearTemp endp
;; @param byte 200 outputData
;; @param byte 200 temp
;; @return reverse(outputData)
reverseString proc uses eax ebx ecx edx
mov al, 0 ;; check (treat as boolean)
mov ecx, sizeof outputData
dec ecx
lcopyloop:
cmp ecx, 0
jl lendcopyloop
cmp al, 1
je lalreadyChecked
cmp outputData[ecx], 0
je updateCheckEnd
updateCheck:
mov al, 1
mov edx, ecx ;; count for loop
updateCheckEnd:
cmp al, 1
jne lignore
lalreadyChecked:
;; copy
mov ah, outputData[ecx]
mov temp[ecx], ah
lignore:
dec ecx
jmp lcopyloop
lendcopyloop:
cmp al, 0
je lendreversestringloop ;; ignore loop in case of empty
;; copy back to outputData in reverse order
mov ecx, edx
mov ebx, 0
lreversestringloop:
cmp ecx, 0
jl lendreversestringloop
;; copy
mov ah, temp[ecx]
mov outputData[ebx], ah
dec ecx
inc ebx
jmp lreversestringloop
lendreversestringloop:
ret
reverseString endp
end main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment