Last active
May 7, 2018 19:41
-
-
Save abdullahnaseer/1322063d6c1a6de6ea6b7870b962e0ad to your computer and use it in GitHub Desktop.
String digits multiplication in MASM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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