-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasm.s
More file actions
457 lines (423 loc) · 9.71 KB
/
asm.s
File metadata and controls
457 lines (423 loc) · 9.71 KB
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
global _start
section .data
; bf code
input_buffer: times 0x1000 db 0x0
cells: times 0x1000 db 0x0
file: db "test.bf", 0x0
section .text
_start:
; save the pointer to the allocated memory
push rbp
mov rbp, rsp
; allocate 0x1000 bytes of memory
; mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
mov rax, 0x9
mov rdi, 0x0
mov rsi, 0x10000
mov rdx, 0x7
mov r10, 0x22
mov r8, 0xffffffff
mov r9, 0x0
syscall
mov r10, rax
; open file
mov rax, 0x2
mov rdi, file
mov rsi, 0x0
mov rdx, 0x0
syscall
; input bf code
mov rdi, rax
mov rsi, input_buffer
mov rdx, 0x1000
mov rax, 0x0
syscall
; compile the bf code
mov rdx, r10
mov r10, input_buffer
call compile
mov rbx, cells
; execute the compiled code
call rdx
; exit 0
mov rax, 0x3c
mov rdi, 0x0
syscall
compile:
; input buffer
; r10 = input_buffer
; rdx = location of the output buffer
push rbp
mov rbp, rsp
mov rcx, rdx ; rcx = location of the output buffer
mov r9, input_buffer ; rdx = location of the input buffer
.loop:
cmp byte [r9], '>'
je .emit_inc_ptr
cmp byte [r9], '<'
je .emit_dec_ptr
cmp byte [r9], '+'
je .emit_inc_val
cmp byte [r9], '-'
je .emit_dec_val
cmp byte [r9], '.'
je .emit_print
cmp byte [r9], ','
je .emit_read
cmp byte [r9], '['
je .emit_loop_start
cmp byte [r9], ']'
je .emit_loop_end
cmp byte [r9], 0x0
je .end
jmp .incloop
.incloop:
add r9, 0x1
jmp .loop
.end:
; write a ret
mov byte [rcx], 0xc3
leave
ret
; assemble the instruction
.emit_inc_ptr:
; emit inc rbx
mov rax, 0x1
mov rsi, 0x3
call emit_inc_reg
add rcx, rax
jmp .incloop
.emit_dec_ptr:
; emit dec rbx
mov rax, 0x1
mov rsi, 0x3
call emit_dec_reg
add rcx, rax
jmp .incloop
.emit_inc_val:
; emit inc byte [rbx]
mov rax, 0x1
mov rsi, 0x3
call emit_inc_val
add rcx, rax
jmp .incloop
.emit_dec_val:
; emit dec byte [rbx]
mov rax, 0x1
mov rsi, 0x3
call emit_dec_val
add rcx, rax
jmp .incloop
.emit_print:
; emit mov rdi, 1
mov rsi, 0x7
mov rdi, 0x1
call emit_mov_reg_int
add rcx, rax
; emit mov rsi, [rbx]
mov rsi, 0x6
mov rdi, 0x3
call emit_mov_reg_reg
add rcx, rax
; emit mov rdx, 1
mov rdi, 0x1
mov rsi, 0x2
call emit_mov_reg_int
add rcx, rax
; emit mov rax, 1
mov rdi, 0x1
mov rsi, 0x0
call emit_mov_reg_int
add rcx, rax
; emit syscall
call emit_syscall
add rcx, rax
jmp .incloop
.emit_read:
; emit mov rdi, 0
mov rsi, 0x7
mov rdi, 0x0
call emit_mov_reg_int
add rcx, rax
; emit mov rsi, [rbx]
mov rsi, 0x6
mov rdi, 0x3
call emit_mov_reg_reg
add rcx, rax
; emit mov rdx, 1
mov rdi, 0x1
mov rsi, 0x2
call emit_mov_reg_int
add rcx, rax
; emit mov rax, 0
mov rdi, 0x0
mov rsi, 0x0
call emit_mov_reg_int
add rcx, rax
; emit syscall
call emit_syscall
add rcx, rax
jmp .incloop
.emit_loop_start:
; save the location of the output buffer
; loop_start:
; emit cmp byte [rbx], 0
mov rsi, 0x3
mov rdi, 0x0
call emit_cmp_mem_int
add rcx, rax
; emit je <offset>
mov rdi, 0x0
mov rsi, 0x3
call emit_je
; save the location of the jne
push rcx
; the offset will be filled in later
add rcx, rax
push rcx
jmp .incloop
.emit_loop_end:
; emit cmp byte [rbx], 0
mov rsi, 0x3
mov rdi, 0x0
call emit_cmp_mem_int
add rcx, rax
; emit jne <offset>
mov rdi, 0x0
mov rsi, 0x3
pop r13 ; r13 = location of the loop start
pop r12 ; r12 = location of the jne
; we have to jump to the location of the loop start
; loop_start - loop_end - sizeof(jmp)
mov r14, rcx
sub r14, r13
add r14, 0x6 ; sizeof(jmp)
; two's complement
not r14
add r14, 0x1
mov rdi, r14
call emit_jne
add rcx, rax
; fill in the offset for the jne which is at r12
add r12, 2
mov r14, rcx
mov r13, r12
add r13, 4
sub r14, r13
mov [r12], dword r14d
jmp .incloop
emit_inc_reg:
; rdi = reg
; rsi = buffer
; rdx = location
; rax = returned length of the encoded instruction
; will assemble inc <reg>
mov [rcx], byte 0x48
mov [rcx + 1], byte 0xff
mov al, 0xc0
or al, sil
mov [rcx + 2], byte al
mov rax, 3
ret
emit_dec_reg:
; rdi = reg
; rsi = buffer
; rdx = location
; rax = returned length of the encoded instruction
; will assemble dec <reg>
mov [rcx], byte 0x48
mov [rcx + 1], byte 0xff
mov al, 0xc8
or al, sil
mov [rcx + 2], byte al
mov rax, 3
ret
emit_xor_reg:
mov al, 0x48
mov [rcx], byte al
mov al, 0x33
mov [rcx + 1], byte al
; modrm = 0xc0 | dst << 3 | src
mov al, 0xc0
or al, sil
shl sil, 3
or al, sil
mov [rcx + 2], byte al
mov rax, 3
ret
emit_inc_val:
; rdi = reg
; rsi = buffer
; rdx = location
; rax = returned length of the encoded instruction
; will assemble inc byte [reg]
; REX + FE /0 INC r/m81 M Valid N.E. Increment r/m byte by 1.
mov [rcx], byte 0b01000000
mov al, 0xfe
mov [rcx + 1], byte al
; modrm = 0x00 | dst << 3 | src
mov al, 0x00
or al, sil
mov [rcx + 2], byte al
mov rax, 3
ret
emit_dec_val:
; rdi = reg
; rsi = buffer
; rdx = location
; rax = returned length of the encoded instruction
; will assemble dec byte [reg]
; REX + FE /1 DEC r/m8* M Valid N.E. Decrement r/m8 by 1.
mov [rcx], byte 0b01000000
mov al, 0xfe
mov [rcx + 1], byte al
; modrm = 0x08 | dst << 3 | src
mov al, 0x08
or al, sil
mov [rcx + 2], byte al
mov rax, 3
ret
emit_mov_reg_int:
; rdi = int
; rsi = reg
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble mov <reg>, <int>
mov [rcx], byte 0xc7
; mod rm = 0xc0 | dst << 3 | src
mov al, 0xc0
or al, sil
mov [rcx + 1], byte al
mov [rcx + 2], dword edi ; imm32
mov rax, 6
ret
emit_mov_reg_reg:
; rdi = reg (dst)
; rsi = reg (src)
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble mov <reg>, <reg>
mov [rcx], byte 0x48
mov al, 0x89
mov [rcx + 1], byte al
; mod rm = 0xc0 | dst << 3 | src
mov al, 0b11000000
or al, sil
shl dil, 3
or al, dil
mov [rcx + 2], byte al
mov rax, 3
ret
emit_mov_reg_mem:
; rdi = reg
; rsi = reg
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble mov <reg>, [<reg>]
mov [rcx], byte 0x48
mov al, 0x8b
mov [rcx + 1], byte al
; mod rm = 0xc0 | dst << 3 | src
shl dil, 3
or sil, dil
mov [rcx + 2], byte sil
mov rax, 3
ret
emit_cmp_reg_int:
; rdi = int
; rsi = reg
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble cmp <reg>, <int>
mov al, 0x48 ; 48 for rex.w, 81 for cmp r/m64, imm32
mov [rcx], byte al
mov al, 0x81
mov [rcx + 1], byte al
; mod rm = 0xc0 | dst << 3 | src
mov al, 0x7
shl al, 3
or al, 0xc0
or al, sil
mov [rcx + 2], byte al
mov [rcx + 3], dword edi ; imm32
mov rax, 7
ret
emit_cmp_mem_int:
; rdi = int
; rsi = reg
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble cmp <reg>, <int>
; cmp byte [rbx], 0
mov [rcx], byte 0x80
mov al, 0x38
or al, sil
mov [rcx + 1], byte al
mov [rcx + 2], byte dil ; imm8
mov rax, 3
ret
emit_jmp:
; rdi = offset
; rsi = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble jmp <offset>
mov al, 0xe9
mov [rcx], byte al
mov [rcx + 1], dword edi ; offset
mov rax, 5
ret
emit_jne:
; rdi = offset
; rsi = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble jne <offset>
mov ax, 0x850f ; 0f85 for jne
mov [rcx], word ax
mov [rcx + 2], dword edi ; offset
mov rax, 6
ret
emit_je:
; rdi = offset
; rsi = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble je <offset>
mov ax, 0x840f ; 0f84 for je
mov [rcx], word ax
mov [rcx + 2], dword edi ; offset
mov rax, 6
ret
emit_add_reg_int:
; rdi = int
; rsi = reg
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble add <reg>, <int>
mov al, 0x48 ; 48 for rex.w, 81 for add r/m64, imm32
mov [rcx], byte al
mov al, 0x81
mov [rcx + 1], byte al
; mod rm = 0xc0 | dst << 3 | src
mov al, 0xc0
or al, sil
mov [rcx + 2], byte al
mov [rcx + 3], dword edi ; imm32
mov rax, 7
ret
emit_syscall:
; rdx = buffer
; rcx = location
; rax = returned length of the encoded instruction
; will assemble syscall
mov ax, 0x050f ; 0f05 for syscall
mov [rcx], word ax
mov rax, 2
ret