3 ; Code for Linux on IA-32.
7 section .text ; start of code
10 global _lmStart ; export the entry point function
11 _lmStart: ; void lmStart(void)
12 mov [__start_esp], esp
15 mov esp, [__start_esp]
16 ; Cleanup can be done here if necessary
25 ; lmExit - Terminate safely from any position in the program
28 lmExit: ; void lmExit(int exitstatus)
29 mov eax, [esp+4] ; pass the exit status through as eax
30 jmp _lmStart.end ; poor man's exception handling
31 ; ret is not necessary
37 ; lmPrintChar - Print one character to stdout (8-bit in 32-bit, LSB)
40 lmPrintChar: ; void lmPrintChar(int chr)
41 ; eax ; will be: syscall number
42 push ebx ; will be: stdout fd
43 ; ecx ; will be: character start address
44 ; edx ; will be: character counter
46 mov edx, 1 ; print one char
47 lea ecx, [esp+8] ; address of the char
48 mov ebx, 1 ; stdout fd
59 ; lmPrintString - Print a null-terminated string to stdout
62 lmPrintString: ; void lmPrintString(char *string)
63 ; eax ; will be: syscall number
64 push ebx ; will be: stdout fd
65 ; ecx ; will be: character start address
66 ; edx ; will be: character counter
68 mov eax, 0 ; prepare for holding a char
69 mov ecx, [esp+8] ; string start address
70 mov edx, -1 ; init char counter to 0
73 inc edx ; char_counter++
74 mov al, [ecx+edx] ; check next char
75 cmp al, 0 ; if != '\0' continue
78 mov ebx, 1 ; stdout fd
89 ; lmPrintInt32s - Print an integer to stdout (signed, 32-bit)
92 lmPrintInt32s: ; void lmPrintInt(int num)
93 ; eax ; will be: dividend
94 push ebx ; will be: divisor
95 ; ecx ; will be: character start address
96 ; edx ; will be: character counter
97 mov eax, [esp+8] ; load num
98 sub esp, 12 ; make space for converted integer
99 lea ecx, [esp+11] ; string offset counter, start at lastchar+1
100 ; so writing ends at 10 and char 11 is reserved
102 mov ebx, 10 ; always divide by 10
104 cmp eax, dword 0 ; if the number is negative, negate
106 neg eax ; great fun at -2147483648. Overflow ftw!
112 dec ecx ; write next char
117 cmp [esp+20], dword 0 ; check for negative number
118 jge .end ; skip for positive
120 mov [ecx], byte '-' ; add - sign
124 sub edx, ecx ; number of chars
125 mov ebx, 1 ; stdout fd
127 int 0x80 ; let the number speak
137 ; lmReadChar - Read a character from stdin (8-bit in 32-bit, LSB)
140 lmReadChar: ; int lmReadChar(void)
143 sub esp, 4 ; make room for character to be read
145 mov edx, 1 ; number of chars
146 mov ecx, esp ; character buffer
147 mov ebx, 0 ; stdin fd
152 jne .ok ; No end of input -> return char
154 mov eax, 0 ; End of Input -> return 0
170 ; lmReadInt32s - Read an integer from stdin (signed, 32-bit)
171 ; Terminated by EOF or LF
174 lmReadInt32s: ; int lmReadInt(void)
176 push esi ; negative number info
177 push edi ; actual number
179 sub esp, 4 ; make room for character to be read
181 mov esi, 0 ; 0 = positive
182 mov edi, 0 ; start with 0
186 mov edx, 1 ; number of chars
187 mov ecx, esp ; character buffer
188 mov ebx, 0 ; stdin fd
193 je .neg ; End of input
210 imul edi, 10 ; shift old digits
211 add edi, eax ; add new digit
222 .skip_loop: ; read and skip until newline is encountered
224 je .end ; if newline found -> end reading
226 mov edx, 1 ; number of chars
227 mov ecx, esp ; character buffer
228 mov ebx, 0 ; stdin fd
233 je .end ; End of input -> end reading
239 mov eax, edi ; Return value: The number read