Last active
March 27, 2017 06:59
-
-
Save Trinitek/268dc4a56cb08dea7a1e to your computer and use it in GitHub Desktop.
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
format PE64 console | |
entry start | |
include 'win64a.inc' | |
section '.text' code readable executable | |
start: | |
and rsp, -16 | |
stdcall dotProduct, vA, vB | |
invoke printf, msg_num, rax | |
stdcall dotProduct, vA, vC | |
invoke printf, msg_num, rax | |
invoke ExitProcess, 0 | |
proc dotProduct vectorA, vectorB | |
mov rax, [rcx] | |
cmp rax, [rdx] | |
je .calculate | |
invoke printf, msg_sizeMismatch | |
mov rax, 0 | |
ret | |
.calculate: | |
mov r8, rcx | |
add r8, 8 | |
mov r9, rdx | |
add r9, 8 | |
mov rcx, rax | |
mov rax, 0 | |
mov rdx, 0 | |
.next: | |
mov rbx, [r9] | |
imul rbx, [r8] | |
add rax, rbx | |
add r8, 8 | |
add r9, 8 | |
loop .next | |
ret | |
endp | |
section '.data' data readable | |
msg_num db "%d", 0x0D, 0x0A, 0 | |
msg_sizeMismatch db "Size mismatch; can't calculate.", 0x0D, 0x0A, 0 | |
struc Vector [symbols] { | |
common | |
.length dq (.end - .symbols) / 8 | |
.symbols dq symbols | |
.end: | |
} | |
vA Vector 1, 3, -5 | |
vB Vector 4, -2, -1 | |
vC Vector 7, 2, 9, 0 | |
section '.idata' import data readable writeable | |
library kernel32, 'KERNEL32.DLL',\ | |
msvcrt, 'MSVCRT.DLL' | |
include 'api/kernel32.inc' | |
import msvcrt,\ | |
printf, 'printf' |
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
format PE64 console ; We specify this executable as a 64-bit PE, and assign it a console instance for standard I/O (alternative is 'GUI') | |
entry start ; Entry point is the 'start' label, a few lines ahead | |
include 'win64a.inc' ; Includes 'stdcall', 'invoke', and 'proc' macros for calling and defining functions | |
section '.text' code readable executable | |
start: | |
and rsp, -16 ; Fix any stack alignment issues -- the stack must align to a 16-byte boundary | |
stdcall dotProduct, vA, vB ; Calls the dotProduct function using the 'fastcall' calling convention (stdcall is an alias to fastcall when targeting 64-bit) | |
invoke printf, msg_num, rax ; Calls the printf function using the 'fastcall' calling convention | |
; | |
stdcall dotProduct, vA, vC ; The difference between invoke and stdcall is that invoke first dereferences the pointer to the function before performing an stdcall | |
invoke printf, msg_num, rax ; ... This is necessary for imported functions such as printf, here | |
invoke ExitProcess, 0 ; Win32 ExitProcess call, with an exit code of 0 | |
proc dotProduct vectorA, vectorB ; The fastcall convention puts the first arg in rcx, and the second in rdx | |
mov rax, [rcx] ; rax <- dereferenced ptr to vectorA, which returns the first QWORD, which is the size of the vector object (see struc below) | |
cmp rax, [rdx] ; compare vectorA.length to vectorB.length --- we dereferenced vectorA because we can only dereference ONE ptr at a time | |
je .calculate ; If the lengths are equal (if 'equal' flag in EFLAGS is set) then jump to '.calculate' | |
invoke printf, msg_sizeMismatch ; Else, print size mismatch message | |
mov rax, 0 ; rax (return value) <- 0 | |
ret ; Return from function | |
.calculate: | |
mov r8, rcx ; Relocate rcx (ptr to vectorA) to r8 -- we will need rcx for the upcoming loop | |
add r8, 8 ; vectorA ptr now points to the first element | |
mov r9, rdx ; Relocate rdx (ptr to vectorB) to r9 | |
add r9, 8 ; vectorB ptr now points to the first element | |
mov rcx, rax ; rcx <- rax (the number of elements in vectorA, A.K.A. vectorA.length -- see above) | |
mov rax, 0 ; clear rax -- this will hold our running total | |
mov rdx, 0 ; clear rdx -- cleared for no reason (?) | |
.next: | |
mov rbx, [r9] ; rbx <- the element pointed at by the vectorB ptr | |
imul rbx, [r8] ; unsigned multiply -- rbx <- rbx * the element pointed at by the vectorA ptr | |
add rax, rbx ; rax (running total) += rbx (multiplication result) | |
add r8, 8 ; vectorA ptr now points to next element | |
add r9, 8 ; vectorB ptr now points to next element | |
loop .next ; RCX--, then goto .next if RCX != 0 | |
ret ; Return from function | |
endp ; End of function definition | |
section '.data' data readable | |
msg_num db "%d", 0x0D, 0x0A, 0 | |
msg_sizeMismatch db "Size mismatch; can't calculate.", 0x0D, 0x0A, 0 | |
; This is a special macro that defines a variable length structure, and is roughly the equivalent to this C struct: | |
; | |
; struct Vector { | |
; uint64_t length; | |
; uint64_t element1; | |
; uint64_t element2; | |
; uint64_t element3; | |
; uint64_t element4; | |
; uint64_t element5; | |
; ... | |
; uint64_t elementN; | |
; } | |
; | |
; Thus, the following... | |
; | |
; vA Vector 1, 3, -5 | |
; | |
; ...creates a struct with the following values: | |
; | |
; vA.length == '3' ((QWORD) three elements in this vector) | |
; vA.symbols == 'dq 1, 3, -5' ((also QWORDs) three QWORDS defined one after another) | |
; | |
; And thus, in memory, the final structure will appear as such: | |
; | |
; dq 3, 1, 3, -5 | |
struc Vector [symbols] { | |
common | |
.length dq (.end - .symbols) / 8 | |
.symbols dq symbols | |
.end: | |
} | |
vA Vector 1, 3, -5 ; dq 3, 1, 3, -5 | |
vB Vector 4, -2, -1 ; dq 3, 4, -2, -1 | |
vC Vector 7, 2, 9, 0 ; dq 4, 7, 2, 9, 0 | |
section '.idata' import data readable writeable | |
library kernel32, 'KERNEL32.DLL',\ ; DLL that contains ExitProcess | |
msvcrt, 'MSVCRT.DLL' ; DLL that contains printf | |
include 'api/kernel32.inc' ; FASM-provided include file that defines ExitProcess | |
import msvcrt,\ ; Declare that we want to import some functions from MSVCRT... | |
printf, 'printf' ; ...import 'printf', and refer to it as 'printf' in our code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment