├── README.md ├── code ├── lesson1 │ └── helloworld.asm ├── lesson10 │ ├── functions.asm │ └── helloworld-10.asm ├── lesson11 │ ├── functions.asm │ └── helloworld-itoa.asm ├── lesson12 │ ├── calculator-addition.asm │ ├── functions.asm │ └── makefile ├── lesson13 │ ├── calculator-subtraction.asm │ ├── functions.asm │ └── makefile ├── lesson14 │ ├── calculator-multiplication.asm │ ├── functions.asm │ └── makefile ├── lesson15 │ ├── calculator-division.asm │ ├── functions.asm │ └── makefile ├── lesson16 │ ├── calculator-atoi.asm │ ├── functions.asm │ └── makefile ├── lesson17 │ ├── functions.asm │ ├── makefile │ └── namespace.asm ├── lesson18 │ ├── fizzbuzz.asm │ ├── functions.asm │ └── makefile ├── lesson19 │ ├── execute.asm │ ├── functions.asm │ └── makefile ├── lesson2 │ └── helloworld.asm ├── lesson20 │ ├── fork.asm │ ├── functions.asm │ └── makefile ├── lesson21 │ ├── functions.asm │ ├── makefile │ └── time.asm ├── lesson22 │ ├── create.asm │ ├── functions.asm │ └── makefile ├── lesson23 │ ├── functions.asm │ ├── makefile │ └── write.asm ├── lesson24 │ ├── functions.asm │ ├── makefile │ └── open.asm ├── lesson25 │ ├── functions.asm │ ├── makefile │ └── read.asm ├── lesson26 │ ├── close.asm │ ├── functions.asm │ └── makefile ├── lesson27 │ ├── functions.asm │ ├── makefile │ ├── readme.txt │ └── seek.asm ├── lesson28 │ ├── functions.asm │ ├── makefile │ ├── readme.txt │ └── unlink.asm ├── lesson29 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson3 │ └── helloworld-len.asm ├── lesson30 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson31 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson32 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson33 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson34 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson35 │ ├── functions.asm │ ├── makefile │ └── socket.asm ├── lesson36 │ ├── crawler.asm │ ├── functions.asm │ └── makefile ├── lesson4 │ └── helloworld-len.asm ├── lesson5 │ ├── functions.asm │ └── helloworld-inc.asm ├── lesson6 │ ├── functions.asm │ └── helloworld-inc.asm ├── lesson7 │ ├── functions.asm │ └── helloworld-lf.asm ├── lesson8 │ ├── functions.asm │ └── helloworld-args.asm └── lesson9 │ ├── functions.asm │ └── helloworld-input.asm └── docs ├── .htaccess ├── assets ├── bootstrap │ ├── css │ │ ├── bootstrap-responsive.min.css │ │ └── bootstrap.min.css │ ├── img │ │ ├── glyphicons-halflings-white.png │ │ └── glyphicons-halflings.png │ └── js │ │ └── bootstrap.min.js ├── fontawesome │ ├── css │ │ ├── all.css │ │ ├── all.min.css │ │ ├── brands.css │ │ ├── brands.min.css │ │ ├── fontawesome.css │ │ ├── fontawesome.min.css │ │ ├── regular.css │ │ ├── regular.min.css │ │ ├── solid.css │ │ ├── solid.min.css │ │ ├── svg-with-js.css │ │ ├── svg-with-js.min.css │ │ ├── v4-shims.css │ │ └── v4-shims.min.css │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 ├── script.js ├── stylesheet.css └── syntax-highlighter │ ├── LGPL-LICENSE │ ├── MIT-LICENSE │ ├── scripts │ ├── shAutoloader.js │ ├── shBrushAsm.js │ ├── shBrushNasm8086.js │ ├── shCore.js │ └── shLegacy.js │ └── styles │ ├── shCore.css │ └── shCoreDefault.css └── index.html /README.md: -------------------------------------------------------------------------------- 1 | assemblytutorials 2 | ================= 3 | 4 | This project was put together to teach myself NASM assembly language on linux. -------------------------------------------------------------------------------- /code/lesson1/helloworld.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program - asmtutor.com 2 | ; Compile with: nasm -f elf helloworld.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld 4 | ; Run with: ./helloworld 5 | 6 | SECTION .data 7 | msg db 'Hello World!', 0Ah ; assign msg variable with your message string 8 | 9 | SECTION .text 10 | global _start 11 | 12 | _start: 13 | 14 | mov edx, 13 ; number of bytes to write - one for each letter plus 0Ah (line feed character) 15 | mov ecx, msg ; move the memory address of our message string into ecx 16 | mov ebx, 1 ; write to the STDOUT file 17 | mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4) 18 | int 80h -------------------------------------------------------------------------------- /code/lesson10/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int slen(String message) 3 | ; String length calculation function 4 | slen: 5 | push ebx 6 | mov ebx, eax 7 | 8 | nextchar: 9 | cmp byte [eax], 0 10 | jz finished 11 | inc eax 12 | jmp nextchar 13 | 14 | finished: 15 | sub eax, ebx 16 | pop ebx 17 | ret 18 | 19 | 20 | ;------------------------------------------ 21 | ; void sprint(String message) 22 | ; String printing function 23 | sprint: 24 | push edx 25 | push ecx 26 | push ebx 27 | push eax 28 | call slen 29 | 30 | mov edx, eax 31 | pop eax 32 | 33 | mov ecx, eax 34 | mov ebx, 1 35 | mov eax, 4 36 | int 80h 37 | 38 | pop ebx 39 | pop ecx 40 | pop edx 41 | ret 42 | 43 | 44 | ;------------------------------------------ 45 | ; void sprintLF(String message) 46 | ; String printing with line feed function 47 | sprintLF: 48 | call sprint 49 | 50 | push eax 51 | mov eax, 0AH 52 | push eax 53 | mov eax, esp 54 | call sprint 55 | pop eax 56 | pop eax 57 | ret 58 | 59 | 60 | ;------------------------------------------ 61 | ; void exit() 62 | ; Exit program and restore resources 63 | quit: 64 | mov ebx, 0 65 | mov eax, 1 66 | int 80h 67 | ret 68 | 69 | -------------------------------------------------------------------------------- /code/lesson10/helloworld-10.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Count to 10) 2 | ; Compile with: nasm -f elf helloworld-10.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-10.o -o helloworld-10 4 | ; Run with: ./helloworld-10 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | mov ecx, 0 ; ecx is initalised to zero. 14 | 15 | nextNumber: 16 | inc ecx ; increment ecx 17 | 18 | mov eax, ecx ; move the address of our integer into eax 19 | add eax, 48 ; add 48 to our number to convert from integer to ascii for printing 20 | push eax ; push eax to the stack 21 | mov eax, esp ; get the address of the character on the stack 22 | call sprintLF ; call our print function 23 | 24 | pop eax ; clean up the stack so we don't have unneeded bytes taking up space 25 | cmp ecx, 10 ; have we reached 10 yet? compare our counter with decimal 10 26 | jne nextNumber ; jump if not equal and keep counting 27 | 28 | call quit -------------------------------------------------------------------------------- /code/lesson11/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; void iprint(Integer number) 3 | ; Integer printing function (itoa) 4 | iprint: 5 | push eax ; preserve eax on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov ecx, 0 ; counter of how many bytes we need to print in the end 10 | 11 | divideLoop: 12 | inc ecx ; count each byte to print - number of characters 13 | mov edx, 0 ; empty edx 14 | mov esi, 10 ; mov 10 into esi 15 | idiv esi ; divide eax by esi 16 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 17 | push edx ; push edx (string representation of an intger) onto the stack 18 | cmp eax, 0 ; can the integer be divided anymore? 19 | jnz divideLoop ; jump if not zero to the label divideLoop 20 | 21 | printLoop: 22 | dec ecx ; count down each byte that we put on the stack 23 | mov eax, esp ; mov the stack pointer into eax for printing 24 | call sprint ; call our string print function 25 | pop eax ; remove last character from the stack to move esp forward 26 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 27 | jnz printLoop ; jump is not zero to the label printLoop 28 | 29 | pop esi ; restore esi from the value we pushed onto the stack at the start 30 | pop edx ; restore edx from the value we pushed onto the stack at the start 31 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 32 | pop eax ; restore eax from the value we pushed onto the stack at the start 33 | ret 34 | 35 | 36 | ;------------------------------------------ 37 | ; void iprintLF(Integer number) 38 | ; Integer printing function with linefeed (itoa) 39 | iprintLF: 40 | call iprint ; call our integer printing function 41 | 42 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 43 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 44 | push eax ; push the linefeed onto the stack so we can get the address 45 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 46 | call sprint ; call our sprint function 47 | pop eax ; remove our linefeed character from the stack 48 | pop eax ; restore the original value of eax before our function was called 49 | ret 50 | 51 | 52 | ;------------------------------------------ 53 | ; int slen(String message) 54 | ; String length calculation function 55 | slen: 56 | push ebx 57 | mov ebx, eax 58 | 59 | nextchar: 60 | cmp byte [eax], 0 61 | jz finished 62 | inc eax 63 | jmp nextchar 64 | 65 | finished: 66 | sub eax, ebx 67 | pop ebx 68 | ret 69 | 70 | 71 | ;------------------------------------------ 72 | ; void sprint(String message) 73 | ; String printing function 74 | sprint: 75 | push edx 76 | push ecx 77 | push ebx 78 | push eax 79 | call slen 80 | 81 | mov edx, eax 82 | pop eax 83 | 84 | mov ecx, eax 85 | mov ebx, 1 86 | mov eax, 4 87 | int 80h 88 | 89 | pop ebx 90 | pop ecx 91 | pop edx 92 | ret 93 | 94 | 95 | ;------------------------------------------ 96 | ; void sprintLF(String message) 97 | ; String printing with line feed function 98 | sprintLF: 99 | call sprint 100 | 101 | push eax 102 | mov eax, 0AH 103 | push eax 104 | mov eax, esp 105 | call sprint 106 | pop eax 107 | pop eax 108 | ret 109 | 110 | 111 | ;------------------------------------------ 112 | ; void exit() 113 | ; Exit program and restore resources 114 | quit: 115 | mov ebx, 0 116 | mov eax, 1 117 | int 80h 118 | ret 119 | 120 | -------------------------------------------------------------------------------- /code/lesson11/helloworld-itoa.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Count to 10 itoa) 2 | ; Compile with: nasm -f elf helloworld-itoa.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-itoa.o -o helloworld-itoa 4 | ; Run with: ./helloworld-itoa 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | mov ecx, 0 14 | 15 | nextNumber: 16 | inc ecx 17 | mov eax, ecx 18 | call iprintLF ; NOTE call our new integer printing function (itoa) 19 | cmp ecx, 10 20 | jne nextNumber 21 | 22 | call quit -------------------------------------------------------------------------------- /code/lesson12/calculator-addition.asm: -------------------------------------------------------------------------------- 1 | ; Calculator (Addition) 2 | ; Compile with: nasm -f elf calculator-addition.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 calculator-addition.o -o calculator-addition 4 | ; Run with: ./calculator-addition 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | mov eax, 90 ; move our first number into eax 14 | mov ebx, 9 ; move our second number into ebx 15 | add eax, ebx ; add ebx to eax 16 | call iprintLF ; call our integer print with linefeed function 17 | 18 | call quit -------------------------------------------------------------------------------- /code/lesson12/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; void iprint(Integer number) 3 | ; Integer printing function (itoa) 4 | iprint: 5 | push eax ; preserve eax on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov ecx, 0 ; counter of how many bytes we need to print in the end 10 | 11 | divideLoop: 12 | inc ecx ; count each byte to print - number of characters 13 | mov edx, 0 ; empty edx 14 | mov esi, 10 ; mov 10 into esi 15 | idiv esi ; divide eax by esi 16 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 17 | push edx ; push edx (string representation of an intger) onto the stack 18 | cmp eax, 0 ; can the integer be divided anymore? 19 | jnz divideLoop ; jump if not zero to the label divideLoop 20 | 21 | printLoop: 22 | dec ecx ; count down each byte that we put on the stack 23 | mov eax, esp ; mov the stack pointer into eax for printing 24 | call sprint ; call our string print function 25 | pop eax ; remove last character from the stack to move esp forward 26 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 27 | jnz printLoop ; jump is not zero to the label printLoop 28 | 29 | pop esi ; restore esi from the value we pushed onto the stack at the start 30 | pop edx ; restore edx from the value we pushed onto the stack at the start 31 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 32 | pop eax ; restore eax from the value we pushed onto the stack at the start 33 | ret 34 | 35 | 36 | ;------------------------------------------ 37 | ; void iprintLF(Integer number) 38 | ; Integer printing function with linefeed (itoa) 39 | iprintLF: 40 | call iprint ; call our integer printing function 41 | 42 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 43 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 44 | push eax ; push the linefeed onto the stack so we can get the address 45 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 46 | call sprint ; call our sprint function 47 | pop eax ; remove our linefeed character from the stack 48 | pop eax ; restore the original value of eax before our function was called 49 | ret 50 | 51 | 52 | ;------------------------------------------ 53 | ; int slen(String message) 54 | ; String length calculation function 55 | slen: 56 | push ebx 57 | mov ebx, eax 58 | 59 | nextchar: 60 | cmp byte [eax], 0 61 | jz finished 62 | inc eax 63 | jmp nextchar 64 | 65 | finished: 66 | sub eax, ebx 67 | pop ebx 68 | ret 69 | 70 | 71 | ;------------------------------------------ 72 | ; void sprint(String message) 73 | ; String printing function 74 | sprint: 75 | push edx 76 | push ecx 77 | push ebx 78 | push eax 79 | call slen 80 | 81 | mov edx, eax 82 | pop eax 83 | 84 | mov ecx, eax 85 | mov ebx, 1 86 | mov eax, 4 87 | int 80h 88 | 89 | pop ebx 90 | pop ecx 91 | pop edx 92 | ret 93 | 94 | 95 | ;------------------------------------------ 96 | ; void sprintLF(String message) 97 | ; String printing with line feed function 98 | sprintLF: 99 | call sprint 100 | 101 | push eax 102 | mov eax, 0AH 103 | push eax 104 | mov eax, esp 105 | call sprint 106 | pop eax 107 | pop eax 108 | ret 109 | 110 | 111 | ;------------------------------------------ 112 | ; void exit() 113 | ; Exit program and restore resources 114 | quit: 115 | mov ebx, 0 116 | mov eax, 1 117 | int 80h 118 | ret 119 | 120 | -------------------------------------------------------------------------------- /code/lesson12/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=calculator-addition 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson13/calculator-subtraction.asm: -------------------------------------------------------------------------------- 1 | ; Calculator (Subtraction) 2 | ; Compile with: nasm -f elf calculator-subtraction.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 calculator-subtraction.o -o calculator-subtraction 4 | ; Run with: ./calculator-subtraction 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | mov eax, 90 ; move our first number into eax 14 | mov ebx, 9 ; move our second number into ebx 15 | sub eax, ebx ; subtract ebx from eax 16 | call iprintLF ; call our integer print with linefeed function 17 | 18 | call quit -------------------------------------------------------------------------------- /code/lesson13/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; void iprint(Integer number) 3 | ; Integer printing function (itoa) 4 | iprint: 5 | push eax ; preserve eax on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov ecx, 0 ; counter of how many bytes we need to print in the end 10 | 11 | divideLoop: 12 | inc ecx ; count each byte to print - number of characters 13 | mov edx, 0 ; empty edx 14 | mov esi, 10 ; mov 10 into esi 15 | idiv esi ; divide eax by esi 16 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 17 | push edx ; push edx (string representation of an intger) onto the stack 18 | cmp eax, 0 ; can the integer be divided anymore? 19 | jnz divideLoop ; jump if not zero to the label divideLoop 20 | 21 | printLoop: 22 | dec ecx ; count down each byte that we put on the stack 23 | mov eax, esp ; mov the stack pointer into eax for printing 24 | call sprint ; call our string print function 25 | pop eax ; remove last character from the stack to move esp forward 26 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 27 | jnz printLoop ; jump is not zero to the label printLoop 28 | 29 | pop esi ; restore esi from the value we pushed onto the stack at the start 30 | pop edx ; restore edx from the value we pushed onto the stack at the start 31 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 32 | pop eax ; restore eax from the value we pushed onto the stack at the start 33 | ret 34 | 35 | 36 | ;------------------------------------------ 37 | ; void iprintLF(Integer number) 38 | ; Integer printing function with linefeed (itoa) 39 | iprintLF: 40 | call iprint ; call our integer printing function 41 | 42 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 43 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 44 | push eax ; push the linefeed onto the stack so we can get the address 45 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 46 | call sprint ; call our sprint function 47 | pop eax ; remove our linefeed character from the stack 48 | pop eax ; restore the original value of eax before our function was called 49 | ret 50 | 51 | 52 | ;------------------------------------------ 53 | ; int slen(String message) 54 | ; String length calculation function 55 | slen: 56 | push ebx 57 | mov ebx, eax 58 | 59 | nextchar: 60 | cmp byte [eax], 0 61 | jz finished 62 | inc eax 63 | jmp nextchar 64 | 65 | finished: 66 | sub eax, ebx 67 | pop ebx 68 | ret 69 | 70 | 71 | ;------------------------------------------ 72 | ; void sprint(String message) 73 | ; String printing function 74 | sprint: 75 | push edx 76 | push ecx 77 | push ebx 78 | push eax 79 | call slen 80 | 81 | mov edx, eax 82 | pop eax 83 | 84 | mov ecx, eax 85 | mov ebx, 1 86 | mov eax, 4 87 | int 80h 88 | 89 | pop ebx 90 | pop ecx 91 | pop edx 92 | ret 93 | 94 | 95 | ;------------------------------------------ 96 | ; void sprintLF(String message) 97 | ; String printing with line feed function 98 | sprintLF: 99 | call sprint 100 | 101 | push eax 102 | mov eax, 0AH 103 | push eax 104 | mov eax, esp 105 | call sprint 106 | pop eax 107 | pop eax 108 | ret 109 | 110 | 111 | ;------------------------------------------ 112 | ; void exit() 113 | ; Exit program and restore resources 114 | quit: 115 | mov ebx, 0 116 | mov eax, 1 117 | int 80h 118 | ret 119 | 120 | -------------------------------------------------------------------------------- /code/lesson13/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=calculator-subtraction 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson14/calculator-multiplication.asm: -------------------------------------------------------------------------------- 1 | ; Calculator (Multiplication) 2 | ; Compile with: nasm -f elf calculator-multiplication.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 calculator-multiplication.o -o calculator-multiplication 4 | ; Run with: ./calculator-multiplication 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | mov eax, 90 ; move our first number into eax 14 | mov ebx, 9 ; move our second number into ebx 15 | mul ebx ; multiply eax by ebx 16 | call iprintLF ; call our integer print with linefeed function 17 | 18 | call quit -------------------------------------------------------------------------------- /code/lesson14/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; void iprint(Integer number) 3 | ; Integer printing function (itoa) 4 | iprint: 5 | push eax ; preserve eax on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov ecx, 0 ; counter of how many bytes we need to print in the end 10 | 11 | divideLoop: 12 | inc ecx ; count each byte to print - number of characters 13 | mov edx, 0 ; empty edx 14 | mov esi, 10 ; mov 10 into esi 15 | idiv esi ; divide eax by esi 16 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 17 | push edx ; push edx (string representation of an intger) onto the stack 18 | cmp eax, 0 ; can the integer be divided anymore? 19 | jnz divideLoop ; jump if not zero to the label divideLoop 20 | 21 | printLoop: 22 | dec ecx ; count down each byte that we put on the stack 23 | mov eax, esp ; mov the stack pointer into eax for printing 24 | call sprint ; call our string print function 25 | pop eax ; remove last character from the stack to move esp forward 26 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 27 | jnz printLoop ; jump is not zero to the label printLoop 28 | 29 | pop esi ; restore esi from the value we pushed onto the stack at the start 30 | pop edx ; restore edx from the value we pushed onto the stack at the start 31 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 32 | pop eax ; restore eax from the value we pushed onto the stack at the start 33 | ret 34 | 35 | 36 | ;------------------------------------------ 37 | ; void iprintLF(Integer number) 38 | ; Integer printing function with linefeed (itoa) 39 | iprintLF: 40 | call iprint ; call our integer printing function 41 | 42 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 43 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 44 | push eax ; push the linefeed onto the stack so we can get the address 45 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 46 | call sprint ; call our sprint function 47 | pop eax ; remove our linefeed character from the stack 48 | pop eax ; restore the original value of eax before our function was called 49 | ret 50 | 51 | 52 | ;------------------------------------------ 53 | ; int slen(String message) 54 | ; String length calculation function 55 | slen: 56 | push ebx 57 | mov ebx, eax 58 | 59 | nextchar: 60 | cmp byte [eax], 0 61 | jz finished 62 | inc eax 63 | jmp nextchar 64 | 65 | finished: 66 | sub eax, ebx 67 | pop ebx 68 | ret 69 | 70 | 71 | ;------------------------------------------ 72 | ; void sprint(String message) 73 | ; String printing function 74 | sprint: 75 | push edx 76 | push ecx 77 | push ebx 78 | push eax 79 | call slen 80 | 81 | mov edx, eax 82 | pop eax 83 | 84 | mov ecx, eax 85 | mov ebx, 1 86 | mov eax, 4 87 | int 80h 88 | 89 | pop ebx 90 | pop ecx 91 | pop edx 92 | ret 93 | 94 | 95 | ;------------------------------------------ 96 | ; void sprintLF(String message) 97 | ; String printing with line feed function 98 | sprintLF: 99 | call sprint 100 | 101 | push eax 102 | mov eax, 0AH 103 | push eax 104 | mov eax, esp 105 | call sprint 106 | pop eax 107 | pop eax 108 | ret 109 | 110 | 111 | ;------------------------------------------ 112 | ; void exit() 113 | ; Exit program and restore resources 114 | quit: 115 | mov ebx, 0 116 | mov eax, 1 117 | int 80h 118 | ret 119 | 120 | -------------------------------------------------------------------------------- /code/lesson14/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=calculator-multiplication 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson15/calculator-division.asm: -------------------------------------------------------------------------------- 1 | ; Calculator (Division) 2 | ; Compile with: nasm -f elf calculator-division.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 calculator-division.o -o calculator-division 4 | ; Run with: ./calculator-division 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | msg1 db ' remainder ' ; a message string to correctly output result 10 | 11 | SECTION .text 12 | global _start 13 | 14 | _start: 15 | 16 | mov eax, 90 ; move our first number into eax 17 | mov ebx, 9 ; move our second number into ebx 18 | div ebx ; divide eax by ebx 19 | call iprint ; call our integer print function on the quotient 20 | mov eax, msg1 ; move our message string into eax 21 | call sprint ; call our string print function 22 | mov eax, edx ; move our remainder into eax 23 | call iprintLF ; call our integer printing with linefeed function 24 | 25 | call quit -------------------------------------------------------------------------------- /code/lesson15/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; void iprint(Integer number) 3 | ; Integer printing function (itoa) 4 | iprint: 5 | push eax ; preserve eax on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov ecx, 0 ; counter of how many bytes we need to print in the end 10 | 11 | divideLoop: 12 | inc ecx ; count each byte to print - number of characters 13 | mov edx, 0 ; empty edx 14 | mov esi, 10 ; mov 10 into esi 15 | idiv esi ; divide eax by esi 16 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 17 | push edx ; push edx (string representation of an intger) onto the stack 18 | cmp eax, 0 ; can the integer be divided anymore? 19 | jnz divideLoop ; jump if not zero to the label divideLoop 20 | 21 | printLoop: 22 | dec ecx ; count down each byte that we put on the stack 23 | mov eax, esp ; mov the stack pointer into eax for printing 24 | call sprint ; call our string print function 25 | pop eax ; remove last character from the stack to move esp forward 26 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 27 | jnz printLoop ; jump is not zero to the label printLoop 28 | 29 | pop esi ; restore esi from the value we pushed onto the stack at the start 30 | pop edx ; restore edx from the value we pushed onto the stack at the start 31 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 32 | pop eax ; restore eax from the value we pushed onto the stack at the start 33 | ret 34 | 35 | 36 | ;------------------------------------------ 37 | ; void iprintLF(Integer number) 38 | ; Integer printing function with linefeed (itoa) 39 | iprintLF: 40 | call iprint ; call our integer printing function 41 | 42 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 43 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 44 | push eax ; push the linefeed onto the stack so we can get the address 45 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 46 | call sprint ; call our sprint function 47 | pop eax ; remove our linefeed character from the stack 48 | pop eax ; restore the original value of eax before our function was called 49 | ret 50 | 51 | 52 | ;------------------------------------------ 53 | ; int slen(String message) 54 | ; String length calculation function 55 | slen: 56 | push ebx 57 | mov ebx, eax 58 | 59 | nextchar: 60 | cmp byte [eax], 0 61 | jz finished 62 | inc eax 63 | jmp nextchar 64 | 65 | finished: 66 | sub eax, ebx 67 | pop ebx 68 | ret 69 | 70 | 71 | ;------------------------------------------ 72 | ; void sprint(String message) 73 | ; String printing function 74 | sprint: 75 | push edx 76 | push ecx 77 | push ebx 78 | push eax 79 | call slen 80 | 81 | mov edx, eax 82 | pop eax 83 | 84 | mov ecx, eax 85 | mov ebx, 1 86 | mov eax, 4 87 | int 80h 88 | 89 | pop ebx 90 | pop ecx 91 | pop edx 92 | ret 93 | 94 | 95 | ;------------------------------------------ 96 | ; void sprintLF(String message) 97 | ; String printing with line feed function 98 | sprintLF: 99 | call sprint 100 | 101 | push eax 102 | mov eax, 0AH 103 | push eax 104 | mov eax, esp 105 | call sprint 106 | pop eax 107 | pop eax 108 | ret 109 | 110 | 111 | ;------------------------------------------ 112 | ; void exit() 113 | ; Exit program and restore resources 114 | quit: 115 | mov ebx, 0 116 | mov eax, 1 117 | int 80h 118 | ret 119 | 120 | -------------------------------------------------------------------------------- /code/lesson15/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=calculator-division 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson16/calculator-atoi.asm: -------------------------------------------------------------------------------- 1 | ; Calculator (ATOI) 2 | ; Compile with: nasm -f elf calculator-atoi.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 calculator-atoi.o -o calculator-atoi 4 | ; Run with: ./calculator-atoi 20 1000 317 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | pop ecx ; first value on the stack is the number of arguments 14 | pop edx ; second value on the stack is the program name (discarded when we initialise edx) 15 | sub ecx, 1 ; decrease ecx by 1 (number of arguments without program name) 16 | mov edx, 0 ; initialise our data register to store additions 17 | 18 | nextArg: 19 | cmp ecx, 0h ; check to see if we have any arguments left 20 | jz noMoreArgs ; if zero flag is set jump to noMoreArgs label (jumping over the end of the loop) 21 | pop eax ; pop the next argument off the stack 22 | call atoi ; convert our ascii string to decimal integer 23 | add edx, eax ; perform our addition logic 24 | dec ecx ; decrease ecx (number of arguments left) by 1 25 | jmp nextArg ; jump to nextArg label 26 | 27 | noMoreArgs: 28 | mov eax, edx ; move our data result into eax for printing 29 | call iprintLF ; call our integer printing with linefeed function 30 | call quit ; call our quit function 31 | -------------------------------------------------------------------------------- /code/lesson16/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our integer value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson16/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=calculator-atoi 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 20 1000 317 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson17/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson17/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=namespace 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson17/namespace.asm: -------------------------------------------------------------------------------- 1 | ; Namespace 2 | ; Compile with: nasm -f elf namespace.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 namespace.o -o namespace 4 | ; Run with: ./namespace 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | msg1 db 'Jumping to finished label.', 0h ; a message string 10 | msg2 db 'Inside subroutine number: ', 0h ; a message string 11 | msg3 db 'Inside subroutine "finished".', 0h ; a message string 12 | 13 | SECTION .text 14 | global _start 15 | 16 | _start: 17 | 18 | subrountineOne: 19 | mov eax, msg1 ; move the address of msg1 into eax 20 | call sprintLF ; call our string printing with linefeed function 21 | jmp .finished ; jump to the local label under the subrountineOne scope 22 | 23 | .finished: 24 | mov eax, msg2 ; move the address of msg2 into eax 25 | call sprint ; call our string printing function 26 | mov eax, 1 ; move the value one into eax (for subroutine number one) 27 | call iprintLF ; call our integer printing function with linefeed function 28 | 29 | subrountineTwo: 30 | mov eax, msg1 ; move the address of msg1 into eax 31 | call sprintLF ; call our string print with linefeed function 32 | jmp .finished ; jump to the local label under the subrountineTwo scope 33 | 34 | .finished: 35 | mov eax, msg2 ; move the address of msg2 into eax 36 | call sprint ; call our string printing function 37 | mov eax, 2 ; move the value two into eax (for subroutine number two) 38 | call iprintLF ; call our integer printing function with linefeed function 39 | 40 | mov eax, msg1 ; move the address of msg1 into eax 41 | call sprintLF ; call our string printing with linefeed function 42 | jmp finished ; jump to the global label finished 43 | 44 | finished: 45 | mov eax, msg3 ; move the address of msg3 into eax 46 | call sprintLF ; call our string printing with linefeed function 47 | call quit ; call our quit function -------------------------------------------------------------------------------- /code/lesson18/fizzbuzz.asm: -------------------------------------------------------------------------------- 1 | ; Fizzbuzz 2 | ; Compile with: nasm -f elf fizzbuzz.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 fizzbuzz.o -o fizzbuzz 4 | ; Run with: ./fizzbuzz 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | fizz db 'Fizz', 0h ; a message string 10 | buzz db 'Buzz', 0h ; a message string 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov esi, 0 ; initialise our checkFizz boolean variable 18 | mov edi, 0 ; initialise our checkBuzz boolean variable 19 | mov ecx, 0 ; initialise our counter variable 20 | 21 | nextNumber: 22 | inc ecx ; increment our counter variable 23 | 24 | .checkFizz: 25 | mov edx, 0 ; clear the edx register - this will hold our remainder after division 26 | mov eax, ecx ; move the value of our counter into eax for division 27 | mov ebx, 3 ; move our number to divide by into ebx (in this case the value is 3) 28 | div ebx ; divide eax by ebx 29 | mov edi, edx ; move our remainder into edi (our checkFizz boolean variable) 30 | cmp edi, 0 ; compare if the remainder is zero (meaning the counter divides by 3) 31 | jne .checkBuzz ; if the remainder is not equal to zero jump to local label checkBuzz 32 | mov eax, fizz ; else move the address of our fizz string into eax for printing 33 | call sprint ; call our string printing function 34 | 35 | .checkBuzz: 36 | mov edx, 0 ; clear the edx register - this will hold our remainder after division 37 | mov eax, ecx ; move the value of our counter into eax for division 38 | mov ebx, 5 ; move our number to divide by into ebx (in this case the value is 5) 39 | div ebx ; divide eax by ebx 40 | mov esi, edx ; move our remainder into edi (our checkBuzz boolean variable) 41 | cmp esi, 0 ; compare if the remainder is zero (meaning the counter divides by 5) 42 | jne .checkInt ; if the remainder is not equal to zero jump to local label checkInt 43 | mov eax, buzz ; else move the address of our buzz string into eax for printing 44 | call sprint ; call our string printing function 45 | 46 | .checkInt: 47 | cmp edi, 0 ; edi contains the remainder after the division in checkFizz 48 | je .continue ; if equal (counter divides by 3) skip printing the integer 49 | cmp esi, 0 ; esi contains the remainder after the division in checkBuzz 50 | je .continue ; if equal (counter divides by 5) skip printing the integer 51 | mov eax, ecx ; else move the value in ecx (our counter) into eax for printing 52 | call iprint ; call our integer printing function 53 | 54 | .continue: 55 | mov eax, 0Ah ; move an ascii linefeed character into eax 56 | push eax ; push the address of eax onto the stack for printing 57 | mov eax, esp ; get the stack pointer (address on the stack of our linefeed char) 58 | call sprint ; call our string printing function to print a line feed 59 | pop eax ; pop the stack so we don't waste resources 60 | cmp ecx, 100 ; compare if our counter is equal to 100 61 | jne nextNumber ; if not equal jump to the start of the loop 62 | 63 | call quit ; else call our quit function -------------------------------------------------------------------------------- /code/lesson18/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson18/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=fizzbuzz 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson19/execute.asm: -------------------------------------------------------------------------------- 1 | ; Execute 2 | ; Compile with: nasm -f elf execute.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 execute.o -o execute 4 | ; Run with: ./execute 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | command db '/bin/echo', 0h ; command to execute 10 | arg1 db 'Hello World!', 0h 11 | arguments dd command 12 | dd arg1 ; arguments to pass to commandline (in this case just one) 13 | dd 0h ; end the struct 14 | environment dd 0h ; arguments to pass as environment variables (inthis case none) end the struct 15 | 16 | SECTION .text 17 | global _start 18 | 19 | _start: 20 | 21 | mov edx, environment ; address of environment variables 22 | mov ecx, arguments ; address of the arguments to pass to the commandline 23 | mov ebx, command ; address of the file to execute 24 | mov eax, 11 ; invoke SYS_EXECVE (kernel opcode 11) 25 | int 80h 26 | 27 | call quit ; call our quit function -------------------------------------------------------------------------------- /code/lesson19/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson19/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=execute 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson2/helloworld.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program - asmtutor.com 2 | ; Compile with: nasm -f elf helloworld.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld.o -o helloworld 4 | ; Run with: ./helloworld 5 | 6 | SECTION .data 7 | msg db 'Hello World!', 0Ah 8 | 9 | SECTION .text 10 | global _start 11 | 12 | _start: 13 | 14 | mov edx, 13 15 | mov ecx, msg 16 | mov ebx, 1 17 | mov eax, 4 18 | int 80h 19 | 20 | mov ebx, 0 ; return 0 status on exit - 'No Errors' 21 | mov eax, 1 ; invoke SYS_EXIT (kernel opcode 1) 22 | int 80h -------------------------------------------------------------------------------- /code/lesson20/fork.asm: -------------------------------------------------------------------------------- 1 | ; Fork 2 | ; Compile with: nasm -f elf fork.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 fork.o -o fork 4 | ; Run with: ./fork 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | childMsg db 'This is the child process', 0h ; a message string 10 | parentMsg db 'This is the parent process', 0h ; a message string 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov eax, 2 ; invoke SYS_FORK (kernel opcode 2) 18 | int 80h 19 | 20 | cmp eax, 0 ; if eax is zero we are in the child process 21 | jz child ; jump if eax is zero to child label 22 | 23 | parent: 24 | mov eax, parentMsg ; inside our parent process move parentMsg into eax 25 | call sprintLF ; call our string printing with linefeed function 26 | 27 | call quit ; quit the parent process 28 | 29 | child: 30 | mov eax, childMsg ; inside our child process move childMsg into eax 31 | call sprintLF ; call our string printing with linefeed function 32 | 33 | call quit ; quit the child process -------------------------------------------------------------------------------- /code/lesson20/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson20/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=fork 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson21/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson21/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=time 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) -------------------------------------------------------------------------------- /code/lesson21/time.asm: -------------------------------------------------------------------------------- 1 | ; Time 2 | ; Compile with: nasm -f elf time.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 time.o -o time 4 | ; Run with: ./time 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | msg db 'Seconds since Jan 01 1970: ', 0h ; a message string 10 | 11 | SECTION .text 12 | global _start 13 | 14 | _start: 15 | 16 | mov eax, msg ; move our message string into eax for printing 17 | call sprint ; call our string printing function 18 | 19 | mov eax, 13 ; invoke SYS_TIME (kernel opcode 13) 20 | int 80h ; call the kernel 21 | 22 | call iprintLF ; call our integer printing function with linefeed 23 | call quit ; call our quit function -------------------------------------------------------------------------------- /code/lesson22/create.asm: -------------------------------------------------------------------------------- 1 | ; Create 2 | ; Compile with: nasm -f elf create.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 create.o -o create 4 | ; Run with: ./create 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to create 10 | 11 | SECTION .text 12 | global _start 13 | 14 | _start: 15 | 16 | mov ecx, 0777o ; set all permissions to read, write, execute 17 | mov ebx, filename ; filename we will create 18 | mov eax, 8 ; invoke SYS_CREAT (kernel opcode 8) 19 | int 80h ; call the kernel 20 | 21 | call quit ; call our quit function 22 | -------------------------------------------------------------------------------- /code/lesson22/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson22/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=create 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | rm -f 'readme.txt' 12 | -------------------------------------------------------------------------------- /code/lesson23/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson23/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=write 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | rm -f 'readme.txt' 12 | -------------------------------------------------------------------------------- /code/lesson23/write.asm: -------------------------------------------------------------------------------- 1 | ; Write 2 | ; Compile with: nasm -f elf write.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 write.o -o write 4 | ; Run with: ./write 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to create 10 | contents db 'Hello world!', 0h ; the contents to write 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov ecx, 0777o ; code continues from lesson 22 18 | mov ebx, filename 19 | mov eax, 8 20 | int 80h 21 | 22 | mov edx, 12 ; number of bytes to write - one for each letter of our contents string 23 | mov ecx, contents ; move the memory address of our contents string into ecx 24 | mov ebx, eax ; move the file descriptor of the file we created into ebx 25 | mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4) 26 | int 80h ; call the kernel 27 | 28 | call quit ; call our quit function 29 | -------------------------------------------------------------------------------- /code/lesson24/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson24/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=open 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | rm -f 'readme.txt' 12 | -------------------------------------------------------------------------------- /code/lesson24/open.asm: -------------------------------------------------------------------------------- 1 | ; Open 2 | ; Compile with: nasm -f elf open.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 open.o -o open 4 | ; Run with: ./open 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to create 10 | contents db 'Hello world!', 0h ; the contents to write 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov ecx, 0777o ; Create file from lesson 22 18 | mov ebx, filename 19 | mov eax, 8 20 | int 80h 21 | 22 | mov edx, 12 ; Write contents to file from lesson 23 23 | mov ecx, contents 24 | mov ebx, eax 25 | mov eax, 4 26 | int 80h 27 | 28 | mov ecx, 0 ; flag for readonly access mode (O_RDONLY) 29 | mov ebx, filename ; filename we created above 30 | mov eax, 5 ; invoke SYS_OPEN (kernel opcode 5) 31 | int 80h ; call the kernel 32 | 33 | call iprintLF ; call our integer printing function 34 | call quit ; call our quit function 35 | -------------------------------------------------------------------------------- /code/lesson25/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson25/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=read 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | rm -f 'readme.txt' 12 | -------------------------------------------------------------------------------- /code/lesson25/read.asm: -------------------------------------------------------------------------------- 1 | ; Read 2 | ; Compile with: nasm -f elf read.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 read.o -o read 4 | ; Run with: ./read 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to create 10 | contents db 'Hello world!', 0h ; the contents to write 11 | 12 | SECTION .bss 13 | fileContents resb 255, ; variable to store file contents 14 | 15 | SECTION .text 16 | global _start 17 | 18 | _start: 19 | 20 | mov ecx, 0777o ; Create file from lesson 22 21 | mov ebx, filename 22 | mov eax, 8 23 | int 80h 24 | 25 | mov edx, 12 ; Write contents to file from lesson 23 26 | mov ecx, contents 27 | mov ebx, eax 28 | mov eax, 4 29 | int 80h 30 | 31 | mov ecx, 0 ; Open file from lesson 24 32 | mov ebx, filename 33 | mov eax, 5 34 | int 80h 35 | 36 | mov edx, 12 ; number of bytes to read - one for each letter of the file contents 37 | mov ecx, fileContents ; move the memory address of our file contents variable into ecx 38 | mov ebx, eax ; move the opened file descriptor into EBX 39 | mov eax, 3 ; invoke SYS_READ (kernel opcode 3) 40 | int 80h ; call the kernel 41 | 42 | mov eax, fileContents ; move the memory address of our file contents variable into eax for printing 43 | call sprintLF ; call our string printing function 44 | 45 | call quit ; call our quit function 46 | -------------------------------------------------------------------------------- /code/lesson26/close.asm: -------------------------------------------------------------------------------- 1 | ; Close 2 | ; Compile with: nasm -f elf close.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 close.o -o close 4 | ; Run with: ./close 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to create 10 | contents db 'Hello world!', 0h ; the contents to write 11 | 12 | SECTION .bss 13 | fileContents resb 255, ; variable to store file contents 14 | 15 | SECTION .text 16 | global _start 17 | 18 | _start: 19 | 20 | mov ecx, 0777o ; Create file from lesson 22 21 | mov ebx, filename 22 | mov eax, 8 23 | int 80h 24 | 25 | mov edx, 12 ; Write contents to file from lesson 23 26 | mov ecx, contents 27 | mov ebx, eax 28 | mov eax, 4 29 | int 80h 30 | 31 | mov ecx, 0 ; Open file from lesson 24 32 | mov ebx, filename 33 | mov eax, 5 34 | int 80h 35 | 36 | mov edx, 12 ; Read file from lesson 25 37 | mov ecx, fileContents 38 | mov ebx, eax 39 | mov eax, 3 40 | int 80h 41 | 42 | mov eax, fileContents 43 | call sprintLF 44 | 45 | mov ebx, ebx ; not needed but used to demonstrate that SYS_CLOSE takes a file descriptor from EBX 46 | mov eax, 6 ; invoke SYS_CLOSE (kernel opcode 6) 47 | int 80h ; call the kernel 48 | 49 | call quit ; call our quit function 50 | -------------------------------------------------------------------------------- /code/lesson26/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson26/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=close 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | rm -f 'readme.txt' 12 | -------------------------------------------------------------------------------- /code/lesson27/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson27/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=seek 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | echo "This file will be updated." > readme.txt 10 | rm -f $(FILENAME).o 11 | rm -f $(FILENAME) 12 | -------------------------------------------------------------------------------- /code/lesson27/readme.txt: -------------------------------------------------------------------------------- 1 | This file will be updated. -------------------------------------------------------------------------------- /code/lesson27/seek.asm: -------------------------------------------------------------------------------- 1 | ; Seek 2 | ; Compile with: nasm -f elf seek.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 seek.o -o seek 4 | ; Run with: ./seek 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to create 10 | contents db '-updated-', 0h ; the contents to write at the start of the file 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov ecx, 1 ; flag for writeonly access mode (O_WRONLY) 18 | mov ebx, filename ; filename of the file to open 19 | mov eax, 5 ; invoke SYS_OPEN (kernel opcode 5) 20 | int 80h ; call the kernel 21 | 22 | mov edx, 2 ; whence argument (SEEK_END) 23 | mov ecx, 0 ; move the cursor 0 bytes 24 | mov ebx, eax ; move the opened file descriptor into EBX 25 | mov eax, 19 ; invoke SYS_LSEEK (kernel opcode 19) 26 | int 80h ; call the kernel 27 | 28 | mov edx, 9 ; number of bytes to write - one for each letter of our contents string 29 | mov ecx, contents ; move the memory address of our contents string into ecx 30 | mov ebx, ebx ; move the opened file descriptor into EBX (not required as EBX already has the FD) 31 | mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4) 32 | int 80h ; call the kernel 33 | 34 | call quit ; call our quit function 35 | -------------------------------------------------------------------------------- /code/lesson28/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson28/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=unlink 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | echo "This file will be deleted." > readme.txt 10 | rm -f $(FILENAME).o 11 | rm -f $(FILENAME) 12 | -------------------------------------------------------------------------------- /code/lesson28/readme.txt: -------------------------------------------------------------------------------- 1 | This file will be deleted. 2 | -------------------------------------------------------------------------------- /code/lesson28/unlink.asm: -------------------------------------------------------------------------------- 1 | ; Unlink 2 | ; Compile with: nasm -f elf unlink.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 unlink.o -o unlink 4 | ; Run with: ./unlink 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | filename db 'readme.txt', 0h ; the filename to delete 10 | 11 | SECTION .text 12 | global _start 13 | 14 | _start: 15 | 16 | mov ebx, filename ; filename we will delete 17 | mov eax, 10 ; invoke SYS_UNLINK (kernel opcode 10) 18 | int 80h ; call the kernel 19 | 20 | call quit ; call our quit function 21 | -------------------------------------------------------------------------------- /code/lesson29/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int atoi(Integer number) 3 | ; Ascii to integer function (atoi) 4 | atoi: 5 | push ebx ; preserve ebx on the stack to be restored after function runs 6 | push ecx ; preserve ecx on the stack to be restored after function runs 7 | push edx ; preserve edx on the stack to be restored after function runs 8 | push esi ; preserve esi on the stack to be restored after function runs 9 | mov esi, eax ; move pointer in eax into esi (our number to convert) 10 | mov eax, 0 ; initialise eax with decimal value 0 11 | mov ecx, 0 ; initialise ecx with decimal value 0 12 | 13 | .multiplyLoop: 14 | xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 15 | mov bl, [esi+ecx] ; move a single byte into ebx register's lower half 16 | cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) 17 | jl .finished ; jump if less than to label finished 18 | cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) 19 | jg .finished ; jump if greater than to label finished 20 | 21 | sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value 22 | add eax, ebx ; add ebx to our interger value in eax 23 | mov ebx, 10 ; move decimal value 10 into ebx 24 | mul ebx ; multiply eax by ebx to get place value 25 | inc ecx ; increment ecx (our counter register) 26 | jmp .multiplyLoop ; continue multiply loop 27 | 28 | .finished: 29 | cmp ecx, 0 ; compare ecx register's value against decimal 0 (our counter register) 30 | je .restore ; jump if equal to 0 (no integer arguments were passed to atoi) 31 | mov ebx, 10 ; move decimal value 10 into ebx 32 | div ebx ; divide eax by value in ebx (in this case 10) 33 | 34 | .restore: 35 | pop esi ; restore esi from the value we pushed onto the stack at the start 36 | pop edx ; restore edx from the value we pushed onto the stack at the start 37 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 38 | pop ebx ; restore ebx from the value we pushed onto the stack at the start 39 | ret 40 | 41 | 42 | ;------------------------------------------ 43 | ; void iprint(Integer number) 44 | ; Integer printing function (itoa) 45 | iprint: 46 | push eax ; preserve eax on the stack to be restored after function runs 47 | push ecx ; preserve ecx on the stack to be restored after function runs 48 | push edx ; preserve edx on the stack to be restored after function runs 49 | push esi ; preserve esi on the stack to be restored after function runs 50 | mov ecx, 0 ; counter of how many bytes we need to print in the end 51 | 52 | .divideLoop: 53 | inc ecx ; count each byte to print - number of characters 54 | mov edx, 0 ; empty edx 55 | mov esi, 10 ; mov 10 into esi 56 | idiv esi ; divide eax by esi 57 | add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction 58 | push edx ; push edx (string representation of an intger) onto the stack 59 | cmp eax, 0 ; can the integer be divided anymore? 60 | jnz .divideLoop ; jump if not zero to the label divideLoop 61 | 62 | .printLoop: 63 | dec ecx ; count down each byte that we put on the stack 64 | mov eax, esp ; mov the stack pointer into eax for printing 65 | call sprint ; call our string print function 66 | pop eax ; remove last character from the stack to move esp forward 67 | cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? 68 | jnz .printLoop ; jump is not zero to the label printLoop 69 | 70 | pop esi ; restore esi from the value we pushed onto the stack at the start 71 | pop edx ; restore edx from the value we pushed onto the stack at the start 72 | pop ecx ; restore ecx from the value we pushed onto the stack at the start 73 | pop eax ; restore eax from the value we pushed onto the stack at the start 74 | ret 75 | 76 | 77 | ;------------------------------------------ 78 | ; void iprintLF(Integer number) 79 | ; Integer printing function with linefeed (itoa) 80 | iprintLF: 81 | call iprint ; call our integer printing function 82 | 83 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 84 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 85 | push eax ; push the linefeed onto the stack so we can get the address 86 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 87 | call sprint ; call our sprint function 88 | pop eax ; remove our linefeed character from the stack 89 | pop eax ; restore the original value of eax before our function was called 90 | ret 91 | 92 | 93 | ;------------------------------------------ 94 | ; int slen(String message) 95 | ; String length calculation function 96 | slen: 97 | push ebx 98 | mov ebx, eax 99 | 100 | .nextchar: 101 | cmp byte [eax], 0 102 | jz .finished 103 | inc eax 104 | jmp .nextchar 105 | 106 | .finished: 107 | sub eax, ebx 108 | pop ebx 109 | ret 110 | 111 | 112 | ;------------------------------------------ 113 | ; void sprint(String message) 114 | ; String printing function 115 | sprint: 116 | push edx 117 | push ecx 118 | push ebx 119 | push eax 120 | call slen 121 | 122 | mov edx, eax 123 | pop eax 124 | 125 | mov ecx, eax 126 | mov ebx, 1 127 | mov eax, 4 128 | int 80h 129 | 130 | pop ebx 131 | pop ecx 132 | pop edx 133 | ret 134 | 135 | 136 | ;------------------------------------------ 137 | ; void sprintLF(String message) 138 | ; String printing with line feed function 139 | sprintLF: 140 | call sprint 141 | 142 | push eax 143 | mov eax, 0AH 144 | push eax 145 | mov eax, esp 146 | call sprint 147 | pop eax 148 | pop eax 149 | ret 150 | 151 | 152 | ;------------------------------------------ 153 | ; void exit() 154 | ; Exit program and restore resources 155 | quit: 156 | mov ebx, 0 157 | mov eax, 1 158 | int 80h 159 | ret 160 | 161 | -------------------------------------------------------------------------------- /code/lesson29/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson29/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | xor eax, eax ; init eax 0 14 | xor ebx, ebx ; init ebx 0 15 | xor edi, edi ; init edi 0 16 | xor esi, esi ; init esi 0 17 | 18 | _socket: 19 | 20 | push byte 6 ; push 6 onto the stack (IPPROTO_TCP) 21 | push byte 1 ; push 1 onto the stack (SOCK_STREAM) 22 | push byte 2 ; push 2 onto the stack (PF_INET) 23 | mov ecx, esp ; move address of arguments into ecx 24 | mov ebx, 1 ; invoke subroutine SOCKET (1) 25 | mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102) 26 | int 80h ; call the kernel 27 | 28 | call iprintLF ; call our integer printing function (print the file descriptor in EAX or -1 on error) 29 | 30 | _exit: 31 | 32 | call quit ; call our quit function 33 | -------------------------------------------------------------------------------- /code/lesson3/helloworld-len.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Calculating string length) 2 | ; Compile with: nasm -f elf helloworld-len.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-len.o -o helloworld-len 4 | ; Run with: ./helloworld-len 5 | 6 | SECTION .data 7 | msg db 'Hello, brave new world!', 0Ah ; we can modify this now without having to update anywhere else in the program 8 | 9 | SECTION .text 10 | global _start 11 | 12 | _start: 13 | 14 | mov ebx, msg ; move the address of our message string into EBX 15 | mov eax, ebx ; move the address in EBX into EAX as well (Both now point to the same segment in memory) 16 | 17 | nextchar: 18 | cmp byte [eax], 0 ; compare the byte pointed to by EAX at this address against zero (Zero is an end of string delimiter) 19 | jz finished ; jump (if the zero flagged has been set) to the point in the code labeled 'finished' 20 | inc eax ; increment the address in EAX by one byte (if the zero flagged has NOT been set) 21 | jmp nextchar ; jump to the point in the code labeled 'nextchar' 22 | 23 | finished: 24 | sub eax, ebx ; subtract the address in EBX from the address in EAX 25 | ; remember both registers started pointing to the same address (see line 15) 26 | ; but EAX has been incremented one byte for each character in the message string 27 | ; when you subtract one memory address from another of the same type 28 | ; the result is number of segments between them - in this case the number of bytes 29 | 30 | mov edx, eax ; EAX now equals the number of bytes in our string 31 | mov ecx, msg ; the rest of the code should be familiar now 32 | mov ebx, 1 33 | mov eax, 4 34 | int 80h 35 | 36 | mov ebx, 0 37 | mov eax, 1 38 | int 80h -------------------------------------------------------------------------------- /code/lesson30/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson30/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | xor eax, eax ; initialize some registers 14 | xor ebx, ebx 15 | xor edi, edi 16 | xor esi, esi 17 | 18 | _socket: 19 | 20 | push byte 6 ; create socket from lesson 29 21 | push byte 1 22 | push byte 2 23 | mov ecx, esp 24 | mov ebx, 1 25 | mov eax, 102 26 | int 80h 27 | 28 | _bind: 29 | 30 | mov edi, eax ; move return value of SYS_SOCKETCALL into edi (file descriptor for new socket, or -1 on error) 31 | push dword 0x00000000 ; push 0 dec onto the stack IP ADDRESS (0.0.0.0) 32 | push word 0x2923 ; push 9001 dec onto stack PORT (reverse byte order) 33 | push word 2 ; push 2 dec onto stack AF_INET 34 | mov ecx, esp ; move address of stack pointer into ecx 35 | push byte 16 ; push 16 dec onto stack (arguments length) 36 | push ecx ; push the address of arguments onto stack 37 | push edi ; push the file descriptor onto stack 38 | mov ecx, esp ; move address of arguments into ecx 39 | mov ebx, 2 ; invoke subroutine BIND (2) 40 | mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102) 41 | int 80h ; call the kernel 42 | 43 | _exit: 44 | 45 | call quit ; call our quit function 46 | -------------------------------------------------------------------------------- /code/lesson31/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson31/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | xor eax, eax ; initialize some registers 14 | xor ebx, ebx 15 | xor edi, edi 16 | xor esi, esi 17 | 18 | _socket: 19 | 20 | push byte 6 ; create socket from lesson 29 21 | push byte 1 22 | push byte 2 23 | mov ecx, esp 24 | mov ebx, 1 25 | mov eax, 102 26 | int 80h 27 | 28 | _bind: 29 | 30 | mov edi, eax ; bind socket from lesson 30 31 | push dword 0x00000000 32 | push word 0x2923 33 | push word 2 34 | mov ecx, esp 35 | push byte 16 36 | push ecx 37 | push edi 38 | mov ecx, esp 39 | mov ebx, 2 40 | mov eax, 102 41 | int 80h 42 | 43 | _listen: 44 | 45 | push byte 1 ; move 1 onto stack (max queue length argument) 46 | push edi ; push the file descriptor onto stack 47 | mov ecx, esp ; move address of arguments into ecx 48 | mov ebx, 4 ; invoke subroutine LISTEN (4) 49 | mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102) 50 | int 80h ; call the kernel 51 | 52 | _exit: 53 | 54 | call quit ; call our quit function 55 | -------------------------------------------------------------------------------- /code/lesson32/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson32/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | xor eax, eax ; initialize some registers 14 | xor ebx, ebx 15 | xor edi, edi 16 | xor esi, esi 17 | 18 | _socket: 19 | 20 | push byte 6 ; create socket from lesson 29 21 | push byte 1 22 | push byte 2 23 | mov ecx, esp 24 | mov ebx, 1 25 | mov eax, 102 26 | int 80h 27 | 28 | _bind: 29 | 30 | mov edi, eax ; bind socket from lesson 30 31 | push dword 0x00000000 32 | push word 0x2923 33 | push word 2 34 | mov ecx, esp 35 | push byte 16 36 | push ecx 37 | push edi 38 | mov ecx, esp 39 | mov ebx, 2 40 | mov eax, 102 41 | int 80h 42 | 43 | _listen: 44 | 45 | push byte 1 ; listen socket from lesson 31 46 | push edi 47 | mov ecx, esp 48 | mov ebx, 4 49 | mov eax, 102 50 | int 80h 51 | 52 | _accept: 53 | 54 | push byte 0 ; push 0 dec onto stack (address length argument) 55 | push byte 0 ; push 0 dec onto stack (address argument) 56 | push edi ; push the file descriptor onto stack 57 | mov ecx, esp ; move address of arguments into ecx 58 | mov ebx, 5 ; invoke subroutine ACCEPT (5) 59 | mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102) 60 | int 80h ; call the kernel 61 | 62 | _exit: 63 | 64 | call quit ; call our quit function 65 | -------------------------------------------------------------------------------- /code/lesson33/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson33/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .bss 9 | buffer resb 255, ; variable to store request headers 10 | 11 | SECTION .text 12 | global _start 13 | 14 | _start: 15 | 16 | xor eax, eax ; initialize some registers 17 | xor ebx, ebx 18 | xor edi, edi 19 | xor esi, esi 20 | 21 | _socket: 22 | 23 | push byte 6 ; create socket from lesson 29 24 | push byte 1 25 | push byte 2 26 | mov ecx, esp 27 | mov ebx, 1 28 | mov eax, 102 29 | int 80h 30 | 31 | _bind: 32 | 33 | mov edi, eax ; bind socket from lesson 30 34 | push dword 0x00000000 35 | push word 0x2923 36 | push word 2 37 | mov ecx, esp 38 | push byte 16 39 | push ecx 40 | push edi 41 | mov ecx, esp 42 | mov ebx, 2 43 | mov eax, 102 44 | int 80h 45 | 46 | _listen: 47 | 48 | push byte 1 ; listen socket from lesson 31 49 | push edi 50 | mov ecx, esp 51 | mov ebx, 4 52 | mov eax, 102 53 | int 80h 54 | 55 | _accept: 56 | 57 | push byte 0 ; accept socket from lesson 32 58 | push byte 0 59 | push edi 60 | mov ecx, esp 61 | mov ebx, 5 62 | mov eax, 102 63 | int 80h 64 | 65 | _fork: 66 | 67 | mov esi, eax ; move return value of SYS_SOCKETCALL into esi (file descriptor for accepted socket, or -1 on error) 68 | mov eax, 2 ; invoke SYS_FORK (kernel opcode 2) 69 | int 80h ; call the kernel 70 | 71 | cmp eax, 0 ; if return value of SYS_FORK in eax is zero we are in the child process 72 | jz _read ; jmp in child process to _read 73 | 74 | jmp _accept ; jmp in parent process to _accept 75 | 76 | _read: 77 | 78 | mov edx, 255 ; number of bytes to read (we will only read the first 255 bytes for simplicity) 79 | mov ecx, buffer ; move the memory address of our buffer variable into ecx 80 | mov ebx, esi ; move esi into ebx (accepted socket file descriptor) 81 | mov eax, 3 ; invoke SYS_READ (kernel opcode 3) 82 | int 80h ; call the kernel 83 | 84 | mov eax, buffer ; move the memory address of our buffer variable into eax for printing 85 | call sprintLF ; call our string printing function 86 | 87 | _exit: 88 | 89 | call quit ; call our quit function 90 | -------------------------------------------------------------------------------- /code/lesson34/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson34/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | ; our response string 10 | response db 'HTTP/1.1 200 OK', 0Dh, 0Ah, 'Content-Type: text/html', 0Dh, 0Ah, 'Content-Length: 14', 0Dh, 0Ah, 0Dh, 0Ah, 'Hello World!', 0Dh, 0Ah, 0h 11 | 12 | SECTION .bss 13 | buffer resb 255, ; variable to store request headers 14 | 15 | SECTION .text 16 | global _start 17 | 18 | _start: 19 | 20 | xor eax, eax ; initialize some registers 21 | xor ebx, ebx 22 | xor edi, edi 23 | xor esi, esi 24 | 25 | _socket: 26 | 27 | push byte 6 ; create socket from lesson 29 28 | push byte 1 29 | push byte 2 30 | mov ecx, esp 31 | mov ebx, 1 32 | mov eax, 102 33 | int 80h 34 | 35 | _bind: 36 | 37 | mov edi, eax ; bind socket from lesson 30 38 | push dword 0x00000000 39 | push word 0x2923 40 | push word 2 41 | mov ecx, esp 42 | push byte 16 43 | push ecx 44 | push edi 45 | mov ecx, esp 46 | mov ebx, 2 47 | mov eax, 102 48 | int 80h 49 | 50 | _listen: 51 | 52 | push byte 1 ; listen socket from lesson 31 53 | push edi 54 | mov ecx, esp 55 | mov ebx, 4 56 | mov eax, 102 57 | int 80h 58 | 59 | _accept: 60 | 61 | push byte 0 ; accept socket from lesson 32 62 | push byte 0 63 | push edi 64 | mov ecx, esp 65 | mov ebx, 5 66 | mov eax, 102 67 | int 80h 68 | 69 | _fork: 70 | 71 | mov esi, eax ; fork socket from lesson 33 72 | mov eax, 2 73 | int 80h 74 | 75 | cmp eax, 0 76 | jz _read 77 | 78 | jmp _accept 79 | 80 | _read: 81 | 82 | mov edx, 255 ; read socket from lesson 33 83 | mov ecx, buffer 84 | mov ebx, esi 85 | mov eax, 3 86 | int 80h 87 | 88 | mov eax, buffer 89 | call sprintLF 90 | 91 | _write: 92 | 93 | mov edx, 78 ; move 78 dec into edx (length in bytes to write) 94 | mov ecx, response ; move address of our response variable into ecx 95 | mov ebx, esi ; move file descriptor into ebx (accepted socket id) 96 | mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4) 97 | int 80h ; call the kernel 98 | 99 | _exit: 100 | 101 | call quit ; call our quit function 102 | -------------------------------------------------------------------------------- /code/lesson35/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=socket 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson35/socket.asm: -------------------------------------------------------------------------------- 1 | ; Socket 2 | ; Compile with: nasm -f elf socket.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 socket.o -o socket 4 | ; Run with: ./socket 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | ; our response string 10 | response db 'HTTP/1.1 200 OK', 0Dh, 0Ah, 'Content-Type: text/html', 0Dh, 0Ah, 'Content-Length: 14', 0Dh, 0Ah, 0Dh, 0Ah, 'Hello World!', 0Dh, 0Ah, 0h 11 | 12 | SECTION .bss 13 | buffer resb 255, ; variable to store request headers 14 | 15 | SECTION .text 16 | global _start 17 | 18 | _start: 19 | 20 | xor eax, eax ; initialize some registers 21 | xor ebx, ebx 22 | xor edi, edi 23 | xor esi, esi 24 | 25 | _socket: 26 | 27 | push byte 6 ; create socket from lesson 29 28 | push byte 1 29 | push byte 2 30 | mov ecx, esp 31 | mov ebx, 1 32 | mov eax, 102 33 | int 80h 34 | 35 | _bind: 36 | 37 | mov edi, eax ; bind socket from lesson 30 38 | push dword 0x00000000 39 | push word 0x2923 40 | push word 2 41 | mov ecx, esp 42 | push byte 16 43 | push ecx 44 | push edi 45 | mov ecx, esp 46 | mov ebx, 2 47 | mov eax, 102 48 | int 80h 49 | 50 | _listen: 51 | 52 | push byte 1 ; listen socket from lesson 31 53 | push edi 54 | mov ecx, esp 55 | mov ebx, 4 56 | mov eax, 102 57 | int 80h 58 | 59 | _accept: 60 | 61 | push byte 0 ; accept socket from lesson 32 62 | push byte 0 63 | push edi 64 | mov ecx, esp 65 | mov ebx, 5 66 | mov eax, 102 67 | int 80h 68 | 69 | _fork: 70 | 71 | mov esi, eax ; fork socket from lesson 33 72 | mov eax, 2 73 | int 80h 74 | 75 | cmp eax, 0 76 | jz _read 77 | 78 | jmp _accept 79 | 80 | _read: 81 | 82 | mov edx, 255 ; read socket from lesson 33 83 | mov ecx, buffer 84 | mov ebx, esi 85 | mov eax, 3 86 | int 80h 87 | 88 | mov eax, buffer 89 | call sprintLF 90 | 91 | _write: 92 | 93 | mov edx, 78 ; write socket from lesson 34 94 | mov ecx, response 95 | mov ebx, esi 96 | mov eax, 4 97 | int 80h 98 | 99 | _close: 100 | 101 | mov ebx, esi ; move esi into ebx (accepted socket file descriptor) 102 | mov eax, 6 ; invoke SYS_CLOSE (kernel opcode 6) 103 | int 80h ; call the kernel 104 | 105 | _exit: 106 | 107 | call quit ; call our quit function 108 | -------------------------------------------------------------------------------- /code/lesson36/crawler.asm: -------------------------------------------------------------------------------- 1 | ; Crawler 2 | ; Compile with: nasm -f elf crawler.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 crawler.o -o crawler 4 | ; Run with: ./crawler 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | ; our request string 10 | request db 'GET / HTTP/1.1', 0Dh, 0Ah, 'Host: 139.162.39.66:80', 0Dh, 0Ah, 0Dh, 0Ah, 0h 11 | 12 | SECTION .bss 13 | buffer resb 1, ; variable to store response 14 | 15 | SECTION .text 16 | global _start 17 | 18 | _start: 19 | 20 | xor eax, eax ; init eax 0 21 | xor ebx, ebx ; init ebx 0 22 | xor edi, edi ; init edi 0 23 | 24 | _socket: 25 | 26 | push byte 6 ; push 6 onto the stack (IPPROTO_TCP) 27 | push byte 1 ; push 1 onto the stack (SOCK_STREAM) 28 | push byte 2 ; push 2 onto the stack (PF_INET) 29 | mov ecx, esp ; move address of arguments into ecx 30 | mov ebx, 1 ; invoke subroutine SOCKET (1) 31 | mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102) 32 | int 80h ; call the kernel 33 | 34 | _connect: 35 | 36 | mov edi, eax ; move return value of SYS_SOCKETCALL into edi (file descriptor for new socket, or -1 on error) 37 | push dword 0x4227a28b ; push 139.162.39.66 onto the stack IP ADDRESS (reverse byte order) 38 | push word 0x5000 ; push 80 onto stack PORT (reverse byte order) 39 | push word 2 ; push 2 dec onto stack AF_INET 40 | mov ecx, esp ; move address of stack pointer into ecx 41 | push byte 16 ; push 16 dec onto stack (arguments length) 42 | push ecx ; push the address of arguments onto stack 43 | push edi ; push the file descriptor onto stack 44 | mov ecx, esp ; move address of arguments into ecx 45 | mov ebx, 3 ; invoke subroutine CONNECT (3) 46 | mov eax, 102 ; invoke SYS_SOCKETCALL (kernel opcode 102) 47 | int 80h ; call the kernel 48 | 49 | _write: 50 | 51 | mov edx, 43 ; move 43 dec into edx (length in bytes to write) 52 | mov ecx, request ; move address of our request variable into ecx 53 | mov ebx, edi ; move file descriptor into ebx (created socket file descriptor) 54 | mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4) 55 | int 80h ; call the kernel 56 | 57 | _read: 58 | 59 | mov edx, 1 ; number of bytes to read (we will read 1 byte at a time) 60 | mov ecx, buffer ; move the memory address of our buffer variable into ecx 61 | mov ebx, edi ; move edi into ebx (created socket file descriptor) 62 | mov eax, 3 ; invoke SYS_READ (kernel opcode 3) 63 | int 80h ; call the kernel 64 | 65 | cmp eax, 0 ; if return value of SYS_READ in eax is zero, we have reached the end of the file 66 | jz _close ; jmp to _close if we have reached the end of the file (zero flag set) 67 | 68 | mov eax, buffer ; move the memory address of our buffer variable into eax for printing 69 | call sprint ; call our string printing function 70 | jmp _read ; jmp to _read 71 | 72 | _close: 73 | 74 | mov ebx, edi ; move edi into ebx (connected socket file descriptor) 75 | mov eax, 6 ; invoke SYS_CLOSE (kernel opcode 6) 76 | int 80h ; call the kernel 77 | 78 | _exit: 79 | 80 | call quit ; call our quit function 81 | -------------------------------------------------------------------------------- /code/lesson36/makefile: -------------------------------------------------------------------------------- 1 | FILENAME=crawler 2 | 3 | all: cleanup 4 | nasm -f elf $(FILENAME).asm 5 | ld -m elf_i386 $(FILENAME).o -o $(FILENAME) 6 | ./$(FILENAME) 7 | 8 | cleanup: 9 | rm -f $(FILENAME).o 10 | rm -f $(FILENAME) 11 | -------------------------------------------------------------------------------- /code/lesson4/helloworld-len.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Subroutines) 2 | ; Compile with: nasm -f elf helloworld-len.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-len.o -o helloworld-len 4 | ; Run with: ./helloworld-len 5 | 6 | SECTION .data 7 | msg db 'Hello, brave new world!', 0AH 8 | 9 | SECTION .text 10 | global _start 11 | 12 | _start: 13 | 14 | mov eax, msg ; move the address of our message string into EAX 15 | call strlen ; call our function to calculate the length of the string 16 | 17 | mov edx, eax ; our function leaves the result in EAX 18 | mov ecx, msg ; this is all the same as before 19 | mov ebx, 1 20 | mov eax, 4 21 | int 80h 22 | 23 | mov ebx, 0 24 | mov eax, 1 25 | int 80h 26 | 27 | strlen: ; this is our first function declaration 28 | push ebx ; push the value in EBX onto the stack to preserve it while we use EBX in this function 29 | mov ebx, eax ; move the address in EAX into EBX (Both point to the same segment in memory) 30 | 31 | nextchar: ; this is the same as lesson3 32 | cmp byte [eax], 0 33 | jz finished 34 | inc eax 35 | jmp nextchar 36 | 37 | finished: 38 | sub eax, ebx 39 | pop ebx ; pop the value on the stack back into EBX 40 | ret ; return to where the function was called -------------------------------------------------------------------------------- /code/lesson5/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int slen(String message) 3 | ; String length calculation function 4 | slen: 5 | push ebx 6 | mov ebx, eax 7 | 8 | nextchar: 9 | cmp byte [eax], 0 10 | jz finished 11 | inc eax 12 | jmp nextchar 13 | 14 | finished: 15 | sub eax, ebx 16 | pop ebx 17 | ret 18 | 19 | 20 | ;------------------------------------------ 21 | ; void sprint(String message) 22 | ; String printing function 23 | sprint: 24 | push edx 25 | push ecx 26 | push ebx 27 | push eax 28 | call slen 29 | 30 | mov edx, eax 31 | pop eax 32 | 33 | mov ecx, eax 34 | mov ebx, 1 35 | mov eax, 4 36 | int 80h 37 | 38 | pop ebx 39 | pop ecx 40 | pop edx 41 | ret 42 | 43 | 44 | ;------------------------------------------ 45 | ; void exit() 46 | ; Exit program and restore resources 47 | quit: 48 | mov ebx, 0 49 | mov eax, 1 50 | int 80h 51 | ret 52 | 53 | -------------------------------------------------------------------------------- /code/lesson5/helloworld-inc.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (External file include) 2 | ; Compile with: nasm -f elf helloworld-inc.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-inc.o -o helloworld-inc 4 | ; Run with: ./helloworld-inc 5 | 6 | %include 'functions.asm' ; include our external file 7 | 8 | SECTION .data 9 | msg1 db 'Hello, brave new world!', 0Ah ; our first message string 10 | msg2 db 'This is how we recycle in NASM.', 0Ah ; our second message string 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov eax, msg1 ; move the address of our first message string into EAX 18 | call sprint ; call our string printing function 19 | 20 | mov eax, msg2 ; move the address of our second message string into EAX 21 | call sprint ; call our string printing function 22 | 23 | call quit ; call our quit function -------------------------------------------------------------------------------- /code/lesson6/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int slen(String message) 3 | ; String length calculation function 4 | slen: 5 | push ebx 6 | mov ebx, eax 7 | 8 | nextchar: 9 | cmp byte [eax], 0 10 | jz finished 11 | inc eax 12 | jmp nextchar 13 | 14 | finished: 15 | sub eax, ebx 16 | pop ebx 17 | ret 18 | 19 | 20 | ;------------------------------------------ 21 | ; void sprint(String message) 22 | ; String printing function 23 | sprint: 24 | push edx 25 | push ecx 26 | push ebx 27 | push eax 28 | call slen 29 | 30 | mov edx, eax 31 | pop eax 32 | 33 | mov ecx, eax 34 | mov ebx, 1 35 | mov eax, 4 36 | int 80h 37 | 38 | pop ebx 39 | pop ecx 40 | pop edx 41 | ret 42 | 43 | 44 | ;------------------------------------------ 45 | ; void exit() 46 | ; Exit program and restore resources 47 | quit: 48 | mov ebx, 0 49 | mov eax, 1 50 | int 80h 51 | ret 52 | 53 | -------------------------------------------------------------------------------- /code/lesson6/helloworld-inc.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (NULL terminating bytes) 2 | ; Compile with: nasm -f elf helloworld-inc.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-inc.o -o helloworld-inc 4 | ; Run with: ./helloworld-inc 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | msg1 db 'Hello, brave new world!', 0Ah, 0h ; NOTE the null terminating byte 10 | msg2 db 'This is how we recycle in NASM.', 0Ah, 0h ; NOTE the null terminating byte 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov eax, msg1 18 | call sprint 19 | 20 | mov eax, msg2 21 | call sprint 22 | 23 | call quit -------------------------------------------------------------------------------- /code/lesson7/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int slen(String message) 3 | ; String length calculation function 4 | slen: 5 | push ebx 6 | mov ebx, eax 7 | 8 | nextchar: 9 | cmp byte [eax], 0 10 | jz finished 11 | inc eax 12 | jmp nextchar 13 | 14 | finished: 15 | sub eax, ebx 16 | pop ebx 17 | ret 18 | 19 | 20 | ;------------------------------------------ 21 | ; void sprint(String message) 22 | ; String printing function 23 | sprint: 24 | push edx 25 | push ecx 26 | push ebx 27 | push eax 28 | call slen 29 | 30 | mov edx, eax 31 | pop eax 32 | 33 | mov ecx, eax 34 | mov ebx, 1 35 | mov eax, 4 36 | int 80h 37 | 38 | pop ebx 39 | pop ecx 40 | pop edx 41 | ret 42 | 43 | 44 | ;------------------------------------------ 45 | ; void sprintLF(String message) 46 | ; String printing with line feed function 47 | sprintLF: 48 | call sprint 49 | 50 | push eax ; push eax onto the stack to preserve it while we use the eax register in this function 51 | mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed 52 | ; as eax is 4 bytes wide, it now contains 0000000Ah 53 | push eax ; push the linefeed onto the stack so we can get the address 54 | ; given that we have a little-endian architecture, eax register bytes are stored in reverse order, 55 | ; this corresponds to stack memory contents of 0Ah, 0h, 0h, 0h, 56 | ; giving us a linefeed followed by a NULL terminating byte 57 | mov eax, esp ; move the address of the current stack pointer into eax for sprint 58 | call sprint ; call our sprint function 59 | pop eax ; remove our linefeed character from the stack 60 | pop eax ; restore the original value of eax before our function was called 61 | ret ; return to our program 62 | 63 | 64 | ;------------------------------------------ 65 | ; void exit() 66 | ; Exit program and restore resources 67 | quit: 68 | mov ebx, 0 69 | mov eax, 1 70 | int 80h 71 | ret 72 | 73 | -------------------------------------------------------------------------------- /code/lesson7/helloworld-lf.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Print with line feed) 2 | ; Compile with: nasm -f elf helloworld-lf.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-lf.o -o helloworld-lf 4 | ; Run with: ./helloworld-lf 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | msg1 db 'Hello, brave new world!', 0h ; NOTE we have removed the line feed character 0AH 10 | msg2 db 'This is how we recycle in NASM.', 0h ; NOTE we have removed the line feed character 0AH 11 | 12 | SECTION .text 13 | global _start 14 | 15 | _start: 16 | 17 | mov eax, msg1 18 | call sprintLF ; NOTE we are calling our new print with linefeed function 19 | 20 | mov eax, msg2 21 | call sprintLF ; NOTE we are calling our new print with linefeed function 22 | 23 | call quit -------------------------------------------------------------------------------- /code/lesson8/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int slen(String message) 3 | ; String length calculation function 4 | slen: 5 | push ebx 6 | mov ebx, eax 7 | 8 | nextchar: 9 | cmp byte [eax], 0 10 | jz finished 11 | inc eax 12 | jmp nextchar 13 | 14 | finished: 15 | sub eax, ebx 16 | pop ebx 17 | ret 18 | 19 | 20 | ;------------------------------------------ 21 | ; void sprint(String message) 22 | ; String printing function 23 | sprint: 24 | push edx 25 | push ecx 26 | push ebx 27 | push eax 28 | call slen 29 | 30 | mov edx, eax 31 | pop eax 32 | 33 | mov ecx, eax 34 | mov ebx, 1 35 | mov eax, 4 36 | int 80h 37 | 38 | pop ebx 39 | pop ecx 40 | pop edx 41 | ret 42 | 43 | 44 | ;------------------------------------------ 45 | ; void sprintLF(String message) 46 | ; String printing with line feed function 47 | sprintLF: 48 | call sprint 49 | 50 | push eax 51 | mov eax, 0AH 52 | push eax 53 | mov eax, esp 54 | call sprint 55 | pop eax 56 | pop eax 57 | ret 58 | 59 | 60 | ;------------------------------------------ 61 | ; void exit() 62 | ; Exit program and restore resources 63 | quit: 64 | mov ebx, 0 65 | mov eax, 1 66 | int 80h 67 | ret 68 | 69 | -------------------------------------------------------------------------------- /code/lesson8/helloworld-args.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Passing arguments from the command line) 2 | ; Compile with: nasm -f elf helloworld-args.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-args.o -o helloworld-args 4 | ; Run with: ./helloworld-args 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .text 9 | global _start 10 | 11 | _start: 12 | 13 | pop ecx ; first value on the stack is the number of arguments 14 | 15 | nextArg: 16 | cmp ecx, 0H ; check to see if we have any arguments left 17 | jz noMoreArgs ; if zero flag is set jump to noMoreArgs label (by jumping over the end of the loop) 18 | pop eax ; pop the next argument off the stack 19 | call sprintLF ; call our print with linefeed function 20 | dec ecx ; decrease edi (number of arguments left) by 1 21 | jmp nextArg ; jump to nextArg label 22 | 23 | noMoreArgs: 24 | call quit -------------------------------------------------------------------------------- /code/lesson9/functions.asm: -------------------------------------------------------------------------------- 1 | ;------------------------------------------ 2 | ; int slen(String message) 3 | ; String length calculation function 4 | slen: 5 | push ebx 6 | mov ebx, eax 7 | 8 | nextchar: 9 | cmp byte [eax], 0 10 | jz finished 11 | inc eax 12 | jmp nextchar 13 | 14 | finished: 15 | sub eax, ebx 16 | pop ebx 17 | ret 18 | 19 | 20 | ;------------------------------------------ 21 | ; void sprint(String message) 22 | ; String printing function 23 | sprint: 24 | push edx 25 | push ecx 26 | push ebx 27 | push eax 28 | call slen 29 | 30 | mov edx, eax 31 | pop eax 32 | 33 | mov ecx, eax 34 | mov ebx, 1 35 | mov eax, 4 36 | int 80h 37 | 38 | pop ebx 39 | pop ecx 40 | pop edx 41 | ret 42 | 43 | 44 | ;------------------------------------------ 45 | ; void sprintLF(String message) 46 | ; String printing with line feed function 47 | sprintLF: 48 | call sprint 49 | 50 | push eax 51 | mov eax, 0AH 52 | push eax 53 | mov eax, esp 54 | call sprint 55 | pop eax 56 | pop eax 57 | ret 58 | 59 | 60 | ;------------------------------------------ 61 | ; void exit() 62 | ; Exit program and restore resources 63 | quit: 64 | mov ebx, 0 65 | mov eax, 1 66 | int 80h 67 | ret 68 | 69 | -------------------------------------------------------------------------------- /code/lesson9/helloworld-input.asm: -------------------------------------------------------------------------------- 1 | ; Hello World Program (Getting input) 2 | ; Compile with: nasm -f elf helloworld-input.asm 3 | ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-input.o -o helloworld-input 4 | ; Run with: ./helloworld-input 5 | 6 | %include 'functions.asm' 7 | 8 | SECTION .data 9 | msg1 db 'Please enter your name: ', 0h ; message string asking user for input 10 | msg2 db 'Hello, ', 0h ; message string to use after user has entered their name 11 | 12 | SECTION .bss 13 | sinput: resb 255 ; reserve a 255 byte space in memory for the users input string 14 | 15 | SECTION .text 16 | global _start 17 | 18 | _start: 19 | 20 | mov eax, msg1 21 | call sprint 22 | 23 | mov edx, 255 ; number of bytes to read 24 | mov ecx, sinput ; reserved space to store our input (known as a buffer) 25 | mov ebx, 0 ; read from the STDIN file 26 | mov eax, 3 ; invoke SYS_READ (kernel opcode 3) 27 | int 80h 28 | 29 | mov eax, msg2 30 | call sprint 31 | 32 | mov eax, sinput ; move our buffer into eax (Note: input contains a linefeed) 33 | call sprint ; call our print function 34 | 35 | call quit 36 | -------------------------------------------------------------------------------- /docs/.htaccess: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------- 2 | # | Forcing `https://` | 3 | # ---------------------------------------------------------------------- 4 | 5 | # Redirect from the `http://` to the `https://` version of the URL. 6 | # 7 | # https://wiki.apache.org/httpd/RewriteHTTPToHTTPS 8 | 9 | # (1) If you're using cPanel AutoSSL or the Let's Encrypt webroot 10 | # method it will fail to validate the certificate if validation 11 | # requests are redirected to HTTPS. Turn on the condition(s) 12 | # you need. 13 | # 14 | # https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml 15 | # https://tools.ietf.org/html/draft-ietf-acme-acme-12 16 | 17 | 18 | RewriteEngine On 19 | RewriteCond %{HTTPS} !=on 20 | RewriteCond %{HTTP_HOST} ^(asmtutor\.com) [NC] 21 | RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 22 | 23 | 24 | # ---------------------------------------------------------------------- 25 | # | Suppressing the `www.` at the beginning of URLs | 26 | # ---------------------------------------------------------------------- 27 | 28 | # Rewrite www.example.com → example.com 29 | 30 | # The same content should never be available under two different 31 | # URLs, especially not with and without `www.` at the beginning. 32 | # This can cause SEO problems (duplicate content), and therefore, 33 | # you should choose one of the alternatives and redirect the other 34 | # one. 35 | # 36 | # (!) NEVER USE BOTH WWW-RELATED RULES AT THE SAME TIME! 37 | 38 | # (1) The rule assumes by default that both HTTP and HTTPS 39 | # environments are available for redirection. 40 | # If your SSL certificate could not handle one of the domains 41 | # used during redirection, you should turn the condition on. 42 | # 43 | # https://github.com/h5bp/server-configs-apache/issues/52 44 | 45 | 46 | RewriteEngine On 47 | # (1) 48 | # RewriteCond %{HTTPS} !=on 49 | RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] 50 | RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L] 51 | 52 | -------------------------------------------------------------------------------- /docs/assets/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/assets/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/brands.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Brands'; 7 | font-style: normal; 8 | font-weight: normal; 9 | font-display: auto; 10 | src: url("../webfonts/fa-brands-400.eot"); 11 | src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } 12 | 13 | .fab { 14 | font-family: 'Font Awesome 5 Brands'; } 15 | -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/brands.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;font-display:auto;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"} -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 400; 9 | font-display: auto; 10 | src: url("../webfonts/fa-regular-400.eot"); 11 | src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } 12 | 13 | .far { 14 | font-family: 'Font Awesome 5 Free'; 15 | font-weight: 400; } 16 | -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:"Font Awesome 5 Free";font-weight:400} -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 900; 9 | font-display: auto; 10 | src: url("../webfonts/fa-solid-900.eot"); 11 | src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } 12 | 13 | .fa, 14 | .fas { 15 | font-family: 'Font Awesome 5 Free'; 16 | font-weight: 900; } 17 | -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} -------------------------------------------------------------------------------- /docs/assets/fontawesome/css/svg-with-js.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | .svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;transform:translate(-50%,-50%);transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;transform:scale(.25);transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;transform:scale(.25);transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;transform:scale(.25);transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;transform:scale(.25);transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;transform:scale(.25);transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto} -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /docs/assets/fontawesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DGivney/assemblytutorials/f818837ca0491915d3d896d9cbdfa9d2507da494/docs/assets/fontawesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /docs/assets/script.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | $('p, li').html(function(i, v) { 4 | return v.replace(/\s(EAX|EBX|ECX|EDX|EBP|ESP|EDI|ESI|BX|BL|BH){1}([^\s]*)/gi, ' $1$2'); 5 | }).html(function(i, v) { 6 | return v.replace(/(SYS_)([^\s]*)/gi, '$1$2'); 7 | }).html(function(i, v) { 8 | return v.replace(/\s(ADD|SUB|MOV|INT|RET|CMP|PUSH|POP|JMP|MUL|DIV)\s/gi, ' $1 '); 9 | }); 10 | 11 | $('.btn-float').hide(); 12 | 13 | $(document).scroll(function() { 14 | var y = $(this).scrollTop(); 15 | 16 | if (y > 400) { 17 | $('.btn-float').fadeIn(); 18 | } else { 19 | $('.btn-float').fadeOut(); 20 | } 21 | }); 22 | 23 | }); 24 | -------------------------------------------------------------------------------- /docs/assets/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* main styles */ 2 | body { padding-top: 60px; padding-bottom: 40px; } 3 | article { padding: 0; } 4 | h5 { font-weight: normal; color: #999999; } 5 | .brand:hover { color: #999999 !important; } 6 | p { margin: 0 0 15px; } 7 | span.register-name { text-transform: uppercase; font-weight: 500; color: #808080; } 8 | span.instruction-name { text-transform: uppercase; font-weight: 500; color: #808080; } 9 | span.function-name { text-transform: lowercase; font-weight: 500; color: #808080; font-style: italic; } 10 | header + p { margin-top: 25px; } 11 | footer p { text-align: right; } 12 | 13 | /* sidebar styles */ 14 | .sidebar-nav { padding: 9px 0; background-color: #ffffff; } 15 | .sidebar-nav { padding-top: 0px; } 16 | .sidebar-nav .nav-header { background-color: #eeeeee; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; } 17 | .sidebar-nav .nav-header:first-child { border-top: none; } 18 | .sidebar-nav a span { padding-left: 10px; font-weight: normal; color: #999999; display: inline; } 19 | 20 | /* article styles */ 21 | .lessons hr { margin: 40px 0 0px 0; } 22 | .lessons article { padding: 40px 0 0 0; } 23 | .lessons article h4 { color: #999999; font-weight: normal; } 24 | .lessons article h5 { color: #006699; font-weight: bold; margin-top: 25px; } 25 | .lessons article h5:before { content: "\05F"; } 26 | .lessons article h5:after { content: "\03A"; } 27 | 28 | /* snippet styles */ 29 | div.snippet { margin: 20px 0px; } 30 | div.snippet div.syntaxhighlighter { font-size: .90em !important; margin: 0 !important; padding: 9px 0; border: 1px solid #eeeeee; -webkit-border-top-right-radius: 6px; -moz-border-radius-topright: 6px; border-top-right-radius: 6px; } 31 | div.snippet span.filename { color: #999999; padding: 3px 8px; background-color: #eeeeee; border-right: 1px solid #dddddd; border-left: 1px solid #dddddd; border-top: 1px solid #dddddd; -webkit-border-top-left-radius: 6px; -webkit-border-top-right-radius: 6px; -moz-border-radius-topleft: 6px; -moz-border-radius-topright: 6px; border-top-left-radius: 6px; border-top-right-radius: 6px; } 32 | div.snippet div.output { font-size: 1em !important; background-color: #eeeeee; border: 1px solid #dddddd; width: 100% !important; -webkit-border-bottom-right-radius: 6px; -webkit-border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -moz-border-radius-bottomleft: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; } 33 | div.snippet div.output .inner { padding: 8px 15px; color: #999999; } 34 | div.snippet div.output .inner span { display: block; clear: both; line-height: 16px; } 35 | 36 | /* fix for bootstrap to play nice with syntaxhighlighter */ 37 | .syntaxhighlighter table td.code .container:before, 38 | .syntaxhighlighter table td.code .container:after { display: none; } 39 | 40 | .btn-float, 41 | .btn-float:active { padding: 15px 17px; line-height: 2rem; font-size: 2rem; position: fixed; bottom: 40px; left: 40px; background-color: #006699; color: #fff; border-radius: 50%; text-align: center; box-shadow: 2px 2px 3px #999; } 42 | .btn-float:hover { color: #ddd; } 43 | 44 | kbd { background-color: #eeeeee; padding: 2px 3px; border-radius: 3px; } 45 | 46 | 47 | 48 | /* Tablet 49 | ------------------------- */ 50 | @media (max-width: 767px) { 51 | footer p { text-align: left; } 52 | .sidebar-nav.affix { 53 | position: static; 54 | width: auto; 55 | top: 0; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /docs/assets/syntax-highlighter/MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003, 2004 Jim Weirich 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /docs/assets/syntax-highlighter/scripts/shAutoloader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (July 02 2010) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2010 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | (function() { 18 | 19 | var sh = SyntaxHighlighter; 20 | 21 | /** 22 | * Provides functionality to dynamically load only the brushes that a needed to render the current page. 23 | * 24 | * There are two syntaxes that autoload understands. For example: 25 | * 26 | * SyntaxHighlighter.autoloader( 27 | * [ 'applescript', 'Scripts/shBrushAppleScript.js' ], 28 | * [ 'actionscript3', 'as3', 'Scripts/shBrushAS3.js' ] 29 | * ); 30 | * 31 | * or a more easily comprehendable one: 32 | * 33 | * SyntaxHighlighter.autoloader( 34 | * 'applescript Scripts/shBrushAppleScript.js', 35 | * 'actionscript3 as3 Scripts/shBrushAS3.js' 36 | * ); 37 | */ 38 | sh.autoloader = function() 39 | { 40 | var list = arguments, 41 | elements = sh.findElements(), 42 | brushes = {}, 43 | scripts = {}, 44 | all = SyntaxHighlighter.all, 45 | allCalled = false, 46 | allParams = null, 47 | i 48 | ; 49 | 50 | SyntaxHighlighter.all = function(params) 51 | { 52 | allParams = params; 53 | allCalled = true; 54 | }; 55 | 56 | function addBrush(aliases, url) 57 | { 58 | for (var i = 0; i < aliases.length; i++) 59 | brushes[aliases[i]] = url; 60 | }; 61 | 62 | function getAliases(item) 63 | { 64 | return item.pop 65 | ? item 66 | : item.split(/\s+/) 67 | ; 68 | } 69 | 70 | // create table of aliases and script urls 71 | for (i = 0; i < list.length; i++) 72 | { 73 | var aliases = getAliases(list[i]), 74 | url = aliases.pop() 75 | ; 76 | 77 | addBrush(aliases, url); 78 | } 79 | 80 | // dynamically add