all:
as _start.s -o _start.o
as asm.s -o asm.o
- ld _start.o asm.o -lc -o a.out
+ as str.s -o str.o
+ as inst.s -o inst.o
+ ld _start.o asm.o str.o inst.o -lc -o a.out
# gcc -fPIE main.c str.s asm.s
clean:
rm *.o
.text
.global printf, putchar
-.global asm_main
+.global asm_main, asm_make_inst
asm_main:
#rdi = argc
#rsi = argv
#rdx = envp
+ push %rbp
+
cmp $2, %rdi
jl _print_usage
je 4f
test %al, %al
- je 5f
+ je 4f
inc %rdi
jmp 1b
2:#before ' ' is opcode
+ movb $0, (%rdi)
+ leaq opcode, %r8
+ movq %rsi, (%r8)
+ jmp 5f
+
3:#before ',' is operand 1
-4:#before '\n' is operand 2
movb $0, (%rdi)
-5:
- push %rax
+ leaq src, %r8
+ movq %rsi, (%r8)
+ jmp 5f
+
+4:#before '\n' or '\0' is operand 2
+ movb $0, (%rdi)
+
push %rax
push %rdi
- mov %rsi, %rdi
- mov $0, %eax
- call printf
- mov $10, %rdi
- call putchar
+ movq %rsi, %rdx
+ movq src, %rsi
+ movq opcode, %rdi
+
+ call asm_make_inst
+
pop %rdi
pop %rax
- pop %rax
-
+5:
test %al,%al
je 6f
inc %rdi
jmp 0b
6:
+ pop %rbp
ret
_print_usage:
push %rdi
pop %rdi
ret
.data
+opcode: .quad 0
+src: .quad 0
usage: .asciz "./a.out asm_code\n"
--- /dev/null
+.text
+.global printf, putchar
+.global asm_strncmp, asm_strcmp
+.global asm_make_inst
+
+N_registers = 4
+N_opcodes = 4
+
+asm_make_inst:
+#rdi = opcode
+#rsi = src
+#rdx = dst
+ push %rbp
+
+ movq %rdi, v_op
+ movq %rsi, v_src
+ movq %rdx, v_dst
+
+ movq v_dst, %rdi
+ leaq __registers, %rsi
+ movl $N_registers, %edx
+ call asm_find_reg
+ movq %rax, v_dst
+
+ movq v_src, %rdi
+ leaq __registers, %rsi
+ movl $N_registers, %edx
+ call asm_find_reg
+ movq %rax, v_src
+
+ movq v_op, %rdi
+ movq v_src, %rax
+ movb 9(%rax), %sil
+ movq v_dst, %rax
+ movb 9(%rax), %dl
+ leaq __opcodes, %rcx
+ movl $N_opcodes, %r8d
+ call asm_find_opcode
+ movq %rax, v_op
+
+ leaq fmt, %rdi
+ movb 10(%rax), %al
+ movzbq %al, %rsi
+ xorq %rax, %rax
+ call printf
+
+ leaq fmt, %rdi
+ movq v_src, %rax
+ movb 8(%rax), %al
+ movzbq %al, %rsi
+ xorq %rax, %rax
+ call printf
+
+ leaq fmt, %rdi
+ movq v_dst, %rax
+ movb 8(%rax), %al
+ movzbq %al, %rsi
+ xorq %rax, %rax
+ call printf
+
+ pop %rbp
+ ret
+
+asm_find_reg:
+#rdi, name of opcode
+#rsi, array pointer to search
+#edx, array len
+
+ push %rbx
+ push %r12
+ push %r13
+
+ movq %rsi, %rbx
+ movl %edx, %r12d
+ movq %rdi, %r13
+
+0:
+ movq %r13, %rdi
+ movq (%rbx), %rsi
+ call asm_strcmp
+
+ test %eax, %eax
+ jne 1f
+
+ movq %rbx, %rax
+ jmp 3f
+1:
+ decl %r12d
+ test %r12d, %r12d
+ je 2f
+
+ addq $16, %rbx
+ jmp 0b
+2:
+ xorq %rax, %rax
+3:
+ pop %r13
+ pop %r12
+ pop %rbx
+ ret
+
+asm_find_opcode:
+#rdi, name of opcode
+#esi, src len of opcode
+#edx, dst len of opcode
+#rcx, array pointer to search
+#r8, array len
+
+ push %rbx
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ movq %rcx, %rbx
+ movl %r8d, %r12d
+
+ movq %rdi, %r13
+ movl %esi, %r14d
+ movl %edx, %r15d
+
+0:
+ movq %r13, %rdi
+ movq (%rbx), %rsi
+ call asm_strcmp
+
+ test %eax, %eax
+ jne 1f
+
+ cmpb 8(%rbx), %r14b
+ jne 1f
+ cmpb 9(%rbx), %r15b
+ jne 1f
+
+ movq %rbx, %rax
+ jmp 2f
+1:
+ decl %r12d
+ test %r12d, %r12d
+ je 2f
+
+ addq $16, %rbx
+ jmp 0b
+2:
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbx
+ ret
+
+.align 4
+.data
+v_op: .quad 0
+v_src: .quad 0
+v_dst: .quad 0
+
+fmt: .asciz "%#x\n"
+
+.align 4
+__mov: .asciz "mov"
+
+__al: .asciz "al"
+__eax: .asciz "eax"
+
+__bl: .asciz "bl"
+__ebx: .asciz "ebx"
+
+.align 4
+__opcodes:
+ .quad __mov
+ .byte 1 # src len
+ .byte 1 # dst len
+ .byte 0x88 # opcode
+ .fill 5, 1, 0
+
+ .quad __mov
+ .byte 2 # src len
+ .byte 2 # dst len
+ .byte 0x89
+ .fill 5, 1, 0
+
+ .quad __mov
+ .byte 4 # src len
+ .byte 4 # dst len
+ .byte 0x89
+ .fill 5, 1, 0
+
+ .quad __mov
+ .byte 8 # src len
+ .byte 8 # dst len
+ .byte 0x89
+ .fill 5, 1, 0
+
+__registers:
+ .quad __al
+ .byte 0 #id
+ .byte 1 #uint8_t
+ .fill 6, 1, 0
+
+ .quad __eax
+ .byte 0 #id
+ .byte 4 #uint32_t
+ .fill 6, 1, 0
+
+ .quad __bl
+ .byte 3 #id
+ .byte 1 #uint8_t
+ .fill 6, 1, 0
+
+ .quad __ebx
+ .byte 3 #id
+ .byte 4 #uint32_t
+ .fill 6, 1, 0