Compare commits
7 Commits
ad9f04fcc4
...
9eeacd4206
Author | SHA1 | Date |
---|---|---|
|
9eeacd4206 | |
|
24aabcf0a0 | |
|
6cccbf0a18 | |
|
94878a596c | |
|
ac59e62b66 | |
|
f777789fc5 | |
|
2c7be9b288 |
|
@ -2,3 +2,4 @@
|
|||
*.pdb
|
||||
*.obj
|
||||
*sublime-workspace
|
||||
*.exe
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
This repo is me working through the book The Art of 64 Bit Assembly.
|
||||
To build listings in the `src/` folder simply call the `build.bat`
|
||||
script with the listing number:
|
||||
|
||||
```batch
|
||||
build 1_8 // don't add .asm extension
|
||||
|
||||
```
|
BIN
program.exe
BIN
program.exe
Binary file not shown.
|
@ -0,0 +1,13 @@
|
|||
.CODE
|
||||
|
||||
option casemap:none ; make all symbols case sensitive (like C)
|
||||
|
||||
public asm_func ; make this visible outside of this source
|
||||
|
||||
asm_func PROC ; start procedure
|
||||
|
||||
ret
|
||||
|
||||
asm_func ENDP ; end procedure
|
||||
|
||||
END
|
|
@ -0,0 +1,15 @@
|
|||
; a user defined proc
|
||||
|
||||
.code
|
||||
|
||||
asm_proc proc
|
||||
ret ; return from the procedure
|
||||
asm_proc endp
|
||||
|
||||
main proc ; the main procedure
|
||||
call asm_proc ; call our proc
|
||||
ret
|
||||
main endp
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
option casemap:none
|
||||
|
||||
.data
|
||||
|
||||
fmt_str byte 'Hello World!', 10, 0 ; here 10 is the newline feed
|
||||
|
||||
.code
|
||||
|
||||
externdef printf:proc
|
||||
|
||||
public asm_func
|
||||
|
||||
asm_func proc
|
||||
sub rsp, 56
|
||||
lea rcx, fmt_str ; load the format string into the RCX register to be used by the printf
|
||||
call printf
|
||||
add rsp, 56
|
||||
ret
|
||||
asm_func endp
|
||||
|
||||
end
|
64
src/1_8.asm
64
src/1_8.asm
|
@ -1,61 +1,61 @@
|
|||
; assembly that shows how to return values to a
|
||||
; a C function
|
||||
|
||||
option casemap:none
|
||||
|
||||
; constants
|
||||
nl = 10
|
||||
maxlen = 256
|
||||
nl = 10 ; newline
|
||||
maxlen = 256 ; max len of the string
|
||||
|
||||
.data
|
||||
|
||||
title_str byte "Listing 1-8", 0
|
||||
prompt byte "Enter a string: ", 0
|
||||
fmt_string byte "User entered: '%s'", nl, 0
|
||||
|
||||
; make `maxlen` copies/duplicates of size byte, each uinitialized
|
||||
input byte maxlen dup (?)
|
||||
title_string byte 'Listing 1_8', 0
|
||||
prompt_string byte 'Enter a string: ', 0
|
||||
format_string byte 'User entered: "%s" ', nl, 0
|
||||
|
||||
input byte maxlen dup (?) ; make maxlen copies of byte, each uninitialized
|
||||
|
||||
.code
|
||||
|
||||
externdef printf:proc
|
||||
externdef readline:proc
|
||||
|
||||
public get_title
|
||||
|
||||
; procedure loads the address of the title_str into the RAX
|
||||
; register, this is the register where C expects to find
|
||||
; the return of this proc. (WINDOWS ABI)
|
||||
;; get_title procedure -------------------------
|
||||
;; get_title moves the address of the byte containing the string "Listing 1_8", 0
|
||||
;; into the RAX register, it does this usig the LEA instruction
|
||||
public get_title
|
||||
get_title proc
|
||||
|
||||
lea rax, title_str ; load address of title string in RAX register
|
||||
ret
|
||||
lea rax, title_string ; load address of title_string into rax
|
||||
ret
|
||||
|
||||
get_title endp
|
||||
|
||||
; ASM Main function
|
||||
public asm_main
|
||||
asm_main proc
|
||||
asm_main proc
|
||||
|
||||
sub rsp, 56
|
||||
|
||||
lea rcx, prompt ; load prompt string address into RCX register
|
||||
call printf ; this is the reigster where ABI tells us to place arguments
|
||||
sub rsp, 56
|
||||
|
||||
mov input, 0 ; ensure the input string is terminated with 0
|
||||
;; first we want to print a prompt, to do this we use the stdio function printf,
|
||||
;; we need to make the arguments for printf avaialble by loading the address of the
|
||||
;; byte prompt_string into RCX
|
||||
lea rcx, prompt_string
|
||||
call printf
|
||||
|
||||
lea rcx, input ; load input address to rcx register
|
||||
mov rdx, maxlen ; move maxlen into rdx register
|
||||
call readline ; use rcx and rdx as arguments to call readline
|
||||
mov input, 0 ;; clear the input
|
||||
|
||||
lea rcx, fmt_string
|
||||
lea rdx, input
|
||||
call printf
|
||||
; read user input by calling readline from out cpp program. We load the required
|
||||
; arguments into the registers RCX, and RDX and then call readline
|
||||
lea rcx, input
|
||||
mov rdx, maxlen
|
||||
call readline
|
||||
|
||||
add rsp, 56
|
||||
; load RCX and RDX with arugments to printf, to print back to the user
|
||||
lea rcx, format_string
|
||||
lea rdx, input
|
||||
call printf
|
||||
|
||||
add rsp, 56
|
||||
ret
|
||||
|
||||
asm_main endp
|
||||
|
||||
end
|
||||
end
|
BIN
src/1_8.exe
BIN
src/1_8.exe
Binary file not shown.
BIN
src/2_2.exe
BIN
src/2_2.exe
Binary file not shown.
|
@ -1,4 +1,9 @@
|
|||
@echo off
|
||||
echo ~~~~ starting build ~~~~
|
||||
|
||||
REM /nolog is dont show MS info at run
|
||||
REM /c is compile dont link
|
||||
REM /Zi is debug info
|
||||
REM /Cp is preserve cases
|
||||
ml64 /nologo /c /Zi /Cp %1.asm
|
||||
cl /nologo /O2 /Zi /utf-8 /EHa /Fe%1.exe c.cpp %1.obj
|
|
@ -8,7 +8,7 @@ extern "C"
|
|||
{
|
||||
void asm_main(void);
|
||||
|
||||
|
||||
// function is defined in the asm file
|
||||
char *get_title(void);
|
||||
|
||||
int readline(char* dest, int maxlen);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
listing_1_9.cpp
|
13
src/main.cpp
13
src/main.cpp
|
@ -2,12 +2,15 @@
|
|||
|
||||
extern "C"
|
||||
{
|
||||
void asm_func(void);
|
||||
};
|
||||
// Function written in ASM
|
||||
void asm_func(void);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int main()
|
||||
{
|
||||
printf("calling asm main\n");
|
||||
printf("calling asm function\n");
|
||||
asm_func();
|
||||
printf("return from asm main\n");
|
||||
printf("returned from asm function\n");
|
||||
|
||||
return(0);
|
||||
}
|
BIN
src/main.exe
BIN
src/main.exe
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue