-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.asm
195 lines (169 loc) · 2.98 KB
/
functions.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
; int atoi(eax buf) -> eax int
atoi:
push ebx
push ecx
push edx
push esi
mov esi, eax ; esi = string buffer
mov eax, 0
mov ecx, 0
.multiplyLoop:
xor ebx,ebx ; reset ebx
mov bl, [esi+ecx] ; move single byte to ebx register
; check if 48 < bl < 57
cmp bl, 48
jl .finished
cmp bl, 57
jg .finished
sub bl, 48
add eax, ebx ; add ebx to total
mov ebx, 10
mul ebx ; total*10
inc ecx
jmp .multiplyLoop
.finished:
cmp ecx, 0
je .restore ; no integer args were passed
mov ebx, 10
div ebx ; remove excess multiply by 10
.restore:
pop esi
pop edx
pop ecx
pop ebx
ret
; void print(eax integer)
iprint:
push eax
push ecx
push edx
push esi
mov ecx, 0
divideLoop:
inc ecx
mov edx, 0
mov esi, 10
idiv esi ; eax/esi, eax is quotient, edx is remainder
add edx, 48 ; convert to ascii digit
push edx
cmp eax, 0 ; loop if it is able to divde
jnz divideLoop
printLoop:
dec ecx
mov eax, esp
call sprint
pop eax
cmp ecx, 0
jnz printLoop
pop esi
pop edx
pop ecx
pop eax
ret
iprintLF:
call iprint
push eax
mov eax, 0Ah
push eax
mov eax, esp
call sprint
pop eax
pop eax
ret
; int slen
slen:
push ebx
mov ebx, eax
nextchar:
cmp byte [eax], 0
jz finished
inc eax
jmp nextchar
finished:
sub eax, ebx
pop ebx
ret
; void sprintn(ecx msg, edx n)
; print msg of length n
sprintn:
push ebx
push eax
mov ebx, 1
mov eax, 4
int 80h
pop eax
pop ebx
ret
; void sprintnLF
sprintnLF:
call sprintn
push eax ; save eax
mov eax, 0Ah ; eax = \n
push eax
mov eax, esp ; eap points to memory of \n
call sprint
pop eax
pop eax
ret
; void sprint
; input eax msg buffer
; touches edx, ecx, ebx, eax
sprint:
; save registers
push edx
push ecx
push ebx
push eax
call slen ; eax is now len
mov edx, eax ; len
pop eax ; restore msg buffer
mov ecx, eax ; buffer
mov ebx, 1 ; stdout
mov eax, 4 ; write syscall
int 80h
; restore registers
pop ebx
pop ecx
pop edx
ret
; void sprintLF
sprintLF:
call sprint
push eax ; save eax
mov eax, 0Ah ; eax = \n
push eax
mov eax, esp ; eap points to memory of \n
call sprint
pop eax
pop eax
ret
printLF:
push eax
mov eax, 0Ah
push eax
mov eax, esp
call sprint
pop eax
pop eax
ret
; void sleepN(eax seconds)
sleepN:
push ecx
push ebx
push 0
push eax
mov ecx, 0 ; rem time
mov ebx, esp ; *timespec rqtp
mov eax, 0xa2 ; nanosleep(*timespec rqtp, *timespec rem)
int 80h
pop eax
pop ebx ; pop 0 off stack
pop ebx
pop ecx
ret
; void exit
quit:
mov ebx, 0
mov eax, 1
int 80h
ret