├── 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 tags to the document body
81 | for (i = 0; i < elements.length; i++)
82 | {
83 | var url = brushes[elements[i].params.brush];
84 |
85 | if (!url)
86 | continue;
87 |
88 | scripts[url] = false;
89 | loadScript(url);
90 | }
91 |
92 | function loadScript(url)
93 | {
94 | var script = document.createElement('script'),
95 | done = false
96 | ;
97 |
98 | script.src = url;
99 | script.type = 'text/javascript';
100 | script.language = 'javascript';
101 | script.onload = script.onreadystatechange = function()
102 | {
103 | if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete'))
104 | {
105 | done = true;
106 | scripts[url] = true;
107 | checkAll();
108 |
109 | // Handle memory leak in IE
110 | script.onload = script.onreadystatechange = null;
111 | script.parentNode.removeChild(script);
112 | }
113 | };
114 |
115 | // sync way of adding script tags to the page
116 | document.body.appendChild(script);
117 | };
118 |
119 | function checkAll()
120 | {
121 | for(var url in scripts)
122 | if (scripts[url] == false)
123 | return;
124 |
125 | if (allCalled)
126 | SyntaxHighlighter.highlight(allParams);
127 | };
128 | };
129 |
130 | })();
131 |
--------------------------------------------------------------------------------
/docs/assets/syntax-highlighter/scripts/shBrushNasm8086.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SyntaxHighlighter
3 | * http://alexgorbatchev.com/
4 | *
5 | * This brush was originally created by UNique
6 | * homepage: http://un-i.tistory.com/
7 | * brush page:
8 | */
9 | SyntaxHighlighter.brushes.Nasm8086 = function () {
10 | var A = "MOV CMOVE CMOVZ CMOVNE CMOVNZ CMOVA CMOVNBE CMOVAE CMOVNB CMOVB CMOVNAE CMOVBE CMOVNA CMOVG CMOVNLE CMOVGE CMOVNL CMOVL CMOVNGE CMOVLE CMOVNG CMOVC CMOVNC CMOVO CMOVNO CMOVS CMOVNS CMOVP CMOVPE CMOVNP CMOVPO XCHG BSWAP XADD CMPXCHG CMPXCHG8B PUSH POP PUSHA PUSHAD POPA POPAD IN OUT CWD CDQ CBW CWDE MOVSX MOVZX ADD ADC SUB SBB IMUL MUL IDIV DIV INC DEC NEG CMP DAA DAS AAA AAS AAM AAD AND OR XOR NOT SAR SHR SAL SHL SHRD SHLD ROR ROL RCR RCL BT BTS BTR BTC BSF BSR SETE SETZ SETNE SETNZ SETA SETNBE SETAE SETNB SETNC SETB SETNAE SETC SETBE SETNA SETG SETNLE SETGE SETNL SETL SETNGE SETLE SETNG SETS SETNS SETO SETNO SETPE SETP SETPO SETNP TEST JMP JE JZ JNE JNZ JA JNBE JAE JNB JB JNAE JBE JNA JG JNLE JGE JNL JL JNGE JLE JNG JC JNC JO JNO JS JNS JPO JNP JPE JP JCXZ JECXZ LOOP LOOPZ LOOPE LOOPNZ LOOPNE CALL RET IRET INT INTO BOUND ENTER LEAVE MOVS MOVSB MOVS MOVSW MOVS MOVSD CMPS CMPSB CMPS CMPSW CMPS CMPSD SCAS SCASB SCAS SCASW SCAS SCASD LODS LODSB LODS LODSW LODS LODSD STOS STOSB STOS STOSW STOS STOSD REP REPE REPZ REPNE REPNZ INS INSB INS INSW INS INSD OUTS OUTSB OUTS OUTSW OUTS OUTSD STC CLC CMC CLD STD LAHF SAHF PUSHF PUSHFD POPF POPFD STI CLI LDS LES LFS LGS LSS LEA NOP UB2 XLAT XLATB CPUID mov cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo xchg bswap xadd cmpxchg cmpxchg8b push pop pusha pushad popa popad in out cwd cdq cbw cwde movsx movzx add adc sub sbb imul mul idiv div inc dec neg cmp daa das aaa aas aam aad and or xor not sar shr sal shl shrd shld ror rol rcr rcl bt bts btr btc bsf bsr sete setz setne setnz seta setnbe setae setnb setnc setb setnae setc setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp test jmp je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp jcxz jecxz loop loopz loope loopnz loopne call ret iret int into bound enter leave movs movsb movs movsw movs movsd cmps cmpsb cmps cmpsw cmps cmpsd scas scasb scas scasw scas scasd lods lodsb lods lodsw lods lodsd stos stosb stos stosw stos stosd rep repe repz repne repnz ins insb ins insw ins insd outs outsb outs outsw outs outsd stc clc cmc cld std lahf sahf pushf pushfd popf popfd sti cli lds les lfs lgs lss lea nop ub2 xlat xlatb cpuid [ ]";
11 | var B = "DB DW DD DQ DT EQU = EVEN PAGE TITLE db dw dd dq dt equ even page title SEGMENT PROC ASSUME END ENDP segment proc assume end endp";
12 | var C = "AX AH AL BX BH BL CX CH CL DX DH DL ax ah al bx bh bl cx ch cl dx dh dl SP BP SI DI sp dp si di IP FL ip fl CS DS SS ES cs ds ss es";
13 | ;this.regexList=[{regex:SyntaxHighlighter.regexLib.doubleQuotedString,css:"string"},{regex:SyntaxHighlighter.regexLib.singleQuotedString,css:"string"},{regex:/^ *;.*/gm,css:"comments"},{regex:new RegExp(this.getKeywords(C),"gm"),css:"color1 bold"},{regex:new RegExp(this.getKeywords(B),"gm"),css:"functions bold"},{regex:new RegExp(this.getKeywords(A),"gm"),css:"keyword bold"}];
14 | };
15 | SyntaxHighlighter.brushes.Nasm8086.prototype=new SyntaxHighlighter.Highlighter();
16 | SyntaxHighlighter.brushes.Nasm8086.aliases=["nasm8086","8086","nasm","asm","masm"];
--------------------------------------------------------------------------------
/docs/assets/syntax-highlighter/scripts/shLegacy.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 | eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3 u={8:{}};u.8={A:4(c,k,l,m,n,o){4 d(a,b){2 a!=1?a:b}4 f(a){2 a!=1?a.E():1}c=c.I(":");3 g=c[0],e={};t={"r":K};M=1;5=8.5;9(3 j R c)e[c[j]]="r";k=f(d(k,5.C));l=f(d(l,5.D));m=f(d(m,5.s));o=f(d(o,5.Q));n=f(d(n,5["x-y"]));2{P:g,C:d(t[e.O],k),D:d(t[e.N],l),s:d({"r":r}[e.s],m),"x-y":d(4(a,b){9(3 h=T S("^"+b+"\\\\[(?\\\\w+)\\\\]$","U"),i=1,p=0;p