SYS_EXIT equ 0x1 SYS_READ equ 0x3 SYS_WRITE equ 0x4 STDIN equ 0x0 STDOUT equ 0x1 STDERR equ 0x2 ; R15 is reserved for action ACTION_LOOP equ 0x0 ACTION_CHAR equ 0x1 ACTION_BACK_TO_OPENING equ 0x2 ACTION_BACK_TO_COMMA equ 0x3 ACTION_BACK_TO_COLON equ 0x4 section .data space db " " endl db 10 backslash db "\\" quote db 0x22 ; " opening_curly db "{" opening_bracket db "[" closing_curly db "}" closing_bracket db "]" comma db "," colon db ":" indent dq 2 ; dq (64 bits) because we are working with 64 bit registers section .bss char resb 1 exitCode resb 1 scope resq 1 in_string resb 1 escape_next resb 1 section .text global _start _start: mov byte[exitCode], 0 mov byte[scope], 0 loop: mov rax, SYS_READ mov rbx, STDIN mov rcx, char mov rdx, 1 int 0x80 ; is at EOF? cmp rax, 0 jle end mov r15, ACTION_LOOP mov al, [char] cmp al, [quote] je case_quote cmp al, [backslash] je case_backslash cmp al, [opening_curly] je case_opening cmp al, [opening_bracket] je case_opening cmp al, [closing_curly] je case_closing cmp al, [closing_bracket] je case_closing cmp al, [comma] je case_comma cmp al, [colon] je case_colon jmp print_char case_quote: mov al, [escape_next] cmp al, 1 je print_char xor byte[in_string], 1 jmp print_char case_backslash: mov byte[escape_next], 1 jmp print_char case_opening: mov r15, ACTION_BACK_TO_OPENING jmp print_char case_opening_back: inc byte[scope] jmp ln_start case_closing: dec byte[scope] mov r15, ACTION_CHAR jmp ln_start case_comma: mov r15, ACTION_BACK_TO_COMMA jmp print_char case_comma_back: mov al, [in_string] cmp al, 0 je ln_start jmp loop case_colon: mov r15, ACTION_BACK_TO_COLON jmp print_char case_colon_back: mov al, [in_string] cmp al, 1 je loop mov r15, ACTION_LOOP mov al, [space] mov byte[char], al jmp print_char print_char: mov rax, SYS_WRITE mov rbx, STDOUT mov rcx, char mov rdx, 1 int 0x80 cmp r15, ACTION_BACK_TO_OPENING je case_opening_back cmp r15, ACTION_BACK_TO_COMMA je case_comma_back cmp r15, ACTION_BACK_TO_COLON je case_colon_back jmp loop ln_start: xor r8, r8 xor r9, r9 xor rax, rax mov rax, [indent] mov rbx, [scope] imul rax, rbx mov r9, rax mov rax, SYS_WRITE mov rbx, STDOUT mov rcx, endl mov rdx, 1 int 0x80 cmp qword[scope], 0 jne ln_loop ln_end: cmp r15, ACTION_CHAR je print_char jmp loop ln_loop: mov rax, SYS_WRITE mov rbx, STDOUT mov rcx, space mov rdx, 1 int 0x80 inc r8 cmp r8, r9 jne ln_loop jmp ln_end end: mov rax, SYS_EXIT mov rbx, [exitCode] int 0x80