@@ -1950,121 +1950,123 @@ void genAssembly(ofstream& outFile, Instr instr, int instrNum) {
19501950
19511951void generate (ofstream& outFile, vector<Instr>& instrs) {
19521952 outFile <<
1953- " extern ExitProcess\n "
1954- " extern GetStdHandle\n "
1955- " extern WriteFile\n "
1956- " extern ReadFile\n "
1953+ " .intel_syntax noprefix\n "
19571954 " \n "
1958- " section .text\n "
1959- " exit: ; exits the program with code in rax\n "
1955+ " .extern ExitProcess\n "
1956+ " .extern GetStdHandle\n "
1957+ " .extern WriteFile\n "
1958+ " .extern ReadFile\n "
1959+ " \n "
1960+ " .text\n "
1961+ " exit: # exits the program with code in rax\n "
19601962 " mov rcx, rax\n "
1961- " and rsp, -16 ; force 16-byte alignment\n "
1963+ " and rsp, -16 # force 16-byte alignment\n "
19621964 " sub rsp, 32\n "
19631965 " call ExitProcess\n "
19641966 " hlt\n "
1965- " error: ; prints ERROR template, instr number: rsi, message: rdx, r8, errorneous value: rcx, exit(1)\n "
1967+ " error: # prints ERROR template, instr number: rsi, message: rdx, r8, errorneous value: rcx, exit(1)\n "
19661968 " push rcx\n "
19671969 " push r8\n "
19681970 " push rdx\n "
19691971 " push rsi\n "
19701972 " mov rdx, ERROR_template\n "
19711973 " mov r8, ERROR_template_len\n "
19721974 " call stderr_write\n "
1973- " pop rax ; print instr number\n "
1975+ " pop rax # print instr number\n "
19741976 " call print_unsigned_err\n "
1975- " pop rdx ; error message\n "
1977+ " pop rdx # error message\n "
19761978 " pop r8\n "
19771979 " call stderr_write\n "
1978- " pop rax ; errorneous value\n "
1980+ " pop rax # errorneous value\n "
19791981 " call print_unsigned_err\n "
19801982 " mov rdx, stdout_buff\n "
1981- " mov BYTE [rdx], 10 ; '\\ n'\n "
1983+ " mov BYTE PTR [rdx], 10 # '\\ n'\n "
19821984 " mov r8, 1\n "
19831985 " call stderr_write\n "
1984- " mov rax, 1 ; exit(1)\n "
1986+ " mov rax, 1 # exit(1)\n "
19851987 " call exit\n "
19861988 " \n "
1987- " get_std_fds: ; prepares all std fds, regs unsafe!\n "
1988- " sub rsp, 32 ; reserve shadow space\n "
1989- " mov rcx, -10 ; stdin fd\n "
1989+ " get_std_fds: # prepares all std fds, regs unsafe!\n "
1990+ " sub rsp, 32 # reserve shadow space\n "
1991+ " mov rcx, -10 # stdin fd\n "
19901992 " call GetStdHandle\n "
19911993 " mov rcx, stdin_fd\n "
19921994 " mov [rcx], rax\n "
1993- " mov rcx, -11 ; stdout fd\n "
1995+ " mov rcx, -11 # stdout fd\n "
19941996 " call GetStdHandle\n "
19951997 " mov rcx, stdout_fd\n "
19961998 " mov [rcx], rax\n "
1997- " mov rcx, -12 ; stderr fd\n "
1999+ " mov rcx, -12 # stderr fd\n "
19982000 " call GetStdHandle\n "
19992001 " mov rcx, stderr_fd\n "
20002002 " mov [rcx], rax\n "
2001- " add rsp, 32 ; remove shadow space\n "
2003+ " add rsp, 32 # remove shadow space\n "
20022004 " ret\n "
20032005 " \n "
2004- " ; rdx - buff, r8 - number of bytes -> rax - number written\n "
2006+ " # rdx - buff, r8 - number of bytes -> rax - number written\n "
20052007 " stdout_write:\n "
2006- " mov rcx, QWORD [rel stdout_fd]\n "
2008+ " mov rcx, QWORD PTR [QWORD PTR stdout_fd]\n "
20072009 " jmp write_file\n "
20082010 " stderr_write:\n "
2009- " mov rcx, QWORD [rel stderr_fd]\n "
2010- " ; fall through to write_file\n "
2011+ " mov rcx, QWORD PTR [QWORD PTR stderr_fd]\n "
2012+ " # fall through to write_file\n "
20112013 " \n "
2012- " ; rcx - fd, rdx - buff, r8 - chars / buffsize -> rax - number read/written\n "
2014+ " # rcx - fd, rdx - buff, r8 - chars / buffsize -> rax - number read/written\n "
20132015 " write_file:\n "
20142016 " mov rax, WriteFile\n "
20152017 " jmp call_winapi_file_op\n "
20162018 " read_file:\n "
20172019 " mov rax, ReadFile\n "
20182020 " call_winapi_file_op:\n "
2019- " mov rbp, rsp ; save rsp @ retval\n "
2020- " and rsp, -16 ; force 16-byte alignment\n "
2021- " push 0 ; number of bytes written/read var\n "
2022- " mov r9, rsp ; ptr to that var\n "
2023- " push 0 ; OVERLAPPED struct null ptr (5th arg) & still aligned\n "
2024- " sub rsp, 32 ; reserve shadow space\n "
2021+ " mov rbp, rsp # save rsp @ retval\n "
2022+ " and rsp, -16 # force 16-byte alignment\n "
2023+ " push 0 # number of bytes written/read var\n "
2024+ " mov r9, rsp # ptr to that var\n "
2025+ " push 0 # OVERLAPPED struct null ptr (5th arg) & still aligned\n "
2026+ " sub rsp, 32 # reserve shadow space\n "
20252027 " call rax\n "
2026- " add rsp, 32+8 ; remove shadow space & overlapped\n "
2027- " pop rax ; num written / read\n "
2028+ " add rsp, 32+8 # remove shadow space & overlapped\n "
2029+ " pop rax # num written / read\n "
20282030 " mov rsp, rbp\n "
20292031 " ret\n "
20302032 " stdin_read:\n "
2031- " mov rcx, stdin_fd ; get chars into stdin_buff\n "
2033+ " mov rcx, stdin_fd # get chars into stdin_buff\n "
20322034 " mov rcx, [rcx]\n "
20332035 " mov rdx, stdin_buff\n "
20342036 " mov r8, STDIN_BUFF_SIZE\n "
20352037 " call read_file\n "
20362038 " \n "
2037- " mov rcx, stdin_buff_char_count ; store how many were read\n "
2039+ " mov rcx, stdin_buff_char_count # store how many were read\n "
20382040 " mov [rcx], rax\n "
2039- " mov rcx, stdin_buff_chars_read ; 0 chars were processed\n "
2040- " mov QWORD [rcx], 0\n "
2041+ " mov rcx, stdin_buff_chars_read # 0 chars were processed\n "
2042+ " mov QWORD PTR [rcx], 0\n "
20412043 " ret\n "
20422044 " \n "
2043- " stdin_peek: ; returns next raw stdin char, does not advance read ptr -> rdx char\n "
2044- " mov rax, stdin_buff_char_count ; if (char_count == chars_read) fill the stdin_buff\n "
2045+ " stdin_peek: # returns next raw stdin char, does not advance read ptr -> rdx char\n "
2046+ " mov rax, stdin_buff_char_count # if (char_count == chars_read) fill the stdin_buff\n "
20452047 " mov rcx, [rax]\n "
20462048 " mov rax, stdin_buff_chars_read\n "
20472049 " cmp rcx, [rax]\n "
20482050 " jne stdin_peek_valid\n "
20492051 " call stdin_read\n "
20502052 " stdin_peek_valid:\n "
2051- " mov rax, stdin_buff_chars_read ; char addr\n "
2053+ " mov rax, stdin_buff_chars_read # char addr\n "
20522054 " mov rcx, stdin_buff\n "
20532055 " add rcx, [rax]\n "
20542056 " \n "
2055- " xor rdx, rdx ; peek the char\n "
2057+ " xor rdx, rdx # peek the char\n "
20562058 " mov dl, [rcx]\n "
20572059 " ret\n "
2058- " get_next_char: ; gets next char from stdin (buffered), advances read ptr -> rdx char\n "
2059- " call stdin_peek ; peek the first unread char\n "
2060- " mov rax, stdin_buff_chars_read ; eat the char\n "
2061- " inc QWORD [rax]\n "
2060+ " get_next_char: # gets next char from stdin (buffered), advances read ptr -> rdx char\n "
2061+ " call stdin_peek # peek the first unread char\n "
2062+ " mov rax, stdin_buff_chars_read # eat the char\n "
2063+ " inc QWORD PTR [rax]\n "
20622064 " ret\n "
20632065 " \n "
2064- " utos: ; n - rax -> r8 char count, r9 - char* str\n "
2065- " xor r8, r8 ; char count\n "
2066- " mov r9, stdout_buff+STDOUT_BUFF_SIZE-1 ; curr buff pos\n "
2067- " mov r10, 10 ; base\n "
2066+ " utos: # n - rax -> r8 char count, r9 - char* str\n "
2067+ " xor r8, r8 # char count\n "
2068+ " mov r9, stdout_buff+STDOUT_BUFF_SIZE-1 # curr buff pos\n "
2069+ " mov r10, 10 # base\n "
20682070 " utos_loop:\n "
20692071 " xor rdx, rdx\n "
20702072 " div r10\n "
@@ -2077,35 +2079,35 @@ void generate(ofstream& outFile, vector<Instr>& instrs) {
20772079 " cmp rax, 0\n "
20782080 " jne utos_loop\n "
20792081 " ret\n "
2080- " print_unsigned: ; rax - n -> rax - num written\n "
2082+ " print_unsigned: # rax - n -> rax - num written\n "
20812083 " call utos\n "
2082- " mov rdx, r9 ; str\n "
2084+ " mov rdx, r9 # str\n "
20832085 " call stdout_write\n "
20842086 " ret\n "
2085- " print_unsigned_err: ; rax - n -> rax - num written\n "
2087+ " print_unsigned_err: # rax - n -> rax - num written\n "
20862088 " call utos\n "
20872089 " mov rcx, stderr_fd\n "
20882090 " mov rcx, [rcx]\n "
2089- " mov rdx, r9 ; str\n "
2091+ " mov rdx, r9 # str\n "
20902092 " call write_file\n "
20912093 " ret\n "
2092- " input_unsigned: ; consumes all numeric chars, constructs uint out of them -> rax num\n "
2093- " xor rax, rax ; out\n "
2094+ " input_unsigned: # consumes all numeric chars, constructs uint out of them -> rax num\n "
2095+ " xor rax, rax # out\n "
20942096 " input_unsigned_loop:\n "
20952097 " push rax\n "
2096- " call stdin_peek ; get next char\n "
2097- " sub rdx, '0' ; isdigit()\n "
2098+ " call stdin_peek # get next char\n "
2099+ " sub rdx, '0' # isdigit()\n "
20982100 " js input_unsigned_end\n "
20992101 " cmp rdx, 9\n "
21002102 " jg input_unsigned_end\n "
21012103 " push rdx\n "
21022104 " \n "
2103- " call get_next_char ; eat the valid char\n "
2104- " pop rcx ; add to parsed\n "
2105+ " call get_next_char # eat the valid char\n "
2106+ " pop rcx # add to parsed\n "
21052107 " pop rax\n "
21062108 " mov r10, 10\n "
21072109 " mul r10\n "
2108- " add rax, rcx ; rax = 10 * rax + rcx\n "
2110+ " add rax, rcx # rax = 10 * rax + rcx\n "
21092111 " \n "
21102112 " mov r10, 65535\n "
21112113 " cmp rax, r10\n "
@@ -2115,14 +2117,14 @@ void generate(ofstream& outFile, vector<Instr>& instrs) {
21152117 " pop rax\n "
21162118 " ret\n "
21172119 " \n "
2118- " global _start\n "
2120+ " . global _start\n "
21192121 " _start:\n "
2120- " ; initialization\n "
2122+ " # initialization\n "
21212123 " call get_std_fds\n "
21222124 " mov rcx, stdin_buff_char_count\n "
2123- " mov QWORD [rcx], 0\n "
2125+ " mov QWORD PTR [rcx], 0\n "
21242126 " mov rcx, stdin_buff_chars_read\n "
2125- " mov QWORD [rcx], 0\n "
2127+ " mov QWORD PTR [rcx], 0\n "
21262128 " \n "
21272129 " mov r13, cells\n "
21282130 " xor r14, r14\n "
@@ -2133,47 +2135,50 @@ void generate(ofstream& outFile, vector<Instr>& instrs) {
21332135 for (int i = 0 ; i < instrs.size (); ++i) {
21342136 instr = instrs[i];
21352137 outFile << " instr_" << i << " :\n " ;
2136- outFile << " ; " << instr.toStr () << ' \n ' ;
2138+ outFile << " # " << instr.toStr () << ' \n ' ;
21372139 genAssembly (outFile, instr, i);
21382140 }
21392141 outFile <<
21402142 " instr_" << instrs.size () << " :\n "
21412143 " jmp end\n "
21422144 " \n "
2143- " ; runtime errors, expect instr number in rsi, errorneous value in rcx\n "
2145+ " # runtime errors, expect instr number in rsi, errorneous value in rcx\n "
21442146 " jmp_error:\n "
21452147 " mov rdx, jmp_error_message\n "
21462148 " mov r8, jmp_error_message_len\n "
21472149 " call error\n "
21482150 " \n "
21492151 " end:\n "
2150- " ; exit(0)\n "
2152+ " # exit(0)\n "
21512153 " mov rax, 0\n "
21522154 " call exit\n "
21532155 " \n "
2154- " section .bss\n "
2155- " cells: resw " << CELLS << " \n "
2156- " stdin_fd: resq 1\n "
2157- " stdout_fd: resq 1\n "
2158- " stderr_fd: resq 1\n "
2159- " stdout_buff: resb STDOUT_BUFF_SIZE\n "
2160- " stdin_buff_chars_read: resq 1\n "
2161- " stdin_buff_char_count: resq 1\n "
2162- " stdin_buff: resb STDIN_BUFF_SIZE\n "
2156+ " .bss\n "
2157+ " .balign 8\n "
2158+ " \n "
2159+ " cells: .skip 2 * " << CELLS << " # resw for memory\n "
2160+ " stdin_fd: .skip 8\n "
2161+ " stdout_fd: .skip 8\n "
2162+ " stderr_fd: .skip 8\n "
2163+ " stdout_buff: .skip STDOUT_BUFF_SIZE # resb\n "
2164+ " stdin_buff: .skip STDIN_BUFF_SIZE # resb\n "
2165+ " stdin_buff_chars_read: .skip 8\n "
2166+ " stdin_buff_char_count: .skip 8\n "
2167+ " \n "
2168+ " .data\n "
2169+ " .equ STDOUT_BUFF_SIZE, " << STDOUT_BUFF_SIZE << " \n "
2170+ " .equ STDIN_BUFF_SIZE, " << STDIN_BUFF_SIZE << " \n "
21632171 " \n "
2164- " section .data \n "
2165- " STDOUT_BUFF_SIZE: EQU " << STDOUT_BUFF_SIZE << " \n "
2166- " STDIN_BUFF_SIZE: EQU " << STDIN_BUFF_SIZE << " \n "
2172+ " # error messages \n "
2173+ " ERROR_template: .ascii \" ERROR: instr_ \ "\n"
2174+ " .equ ERROR_template_len, . - ERROR_template \n "
21672175 " \n "
2168- " ; error messages\n "
2169- " ERROR_template: db 10,\" ERROR: instr_\"\n "
2170- " ERROR_template_len: EQU $-ERROR_template\n "
2171- " jmp_error_message: db \" : jmp destination out of bounds: \"\n "
2172- " jmp_error_message_len: EQU $-jmp_error_message\n "
2176+ " jmp_error_message: .ascii \" : jmp destination out of bounds: \"\n "
2177+ " .equ jmp_error_message_len, . - jmp_error_message\n "
21732178 " \n "
2174- " ; instruction addresses\n "
2175- " instruction_count: EQU " << instrs.size () << " \n "
2176- " instruction_offsets: dq " ;
2179+ " # instruction addresses\n "
2180+ " .equ instruction_count, " << instrs.size () << " \n "
2181+ " instruction_offsets: .quad " ;
21772182
21782183 outFile << " instr_0" ;
21792184 for (int i = 1 ; i <= instrs.size (); ++i) {
@@ -2304,17 +2309,18 @@ void removeFile(fs::path file) {
23042309}
23052310int compileAndRun (Flags& flags) {
23062311 runCmdEchoed ({
2307- " nasm" , " -fwin64" , " -g" , " -F cv8" ,
2308- flags.filePathStr (" asm" )
2312+ " gcc" , " -c" ,
2313+ " -o" , flags.filePathStr (" obj" ),
2314+ flags.filePathStr (" s" )
23092315 }, flags);
23102316 runCmdEchoed ({
23112317 " gcc" , " -nostartfiles" , " -Wl,-e,_start" , " -lkernel32" ,
23122318 " -o" , flags.filePathStr (" exe" ), " -g" , flags.filePathStr (" obj" )
23132319 }, flags);
23142320 if (flags.keepAsm ) {
2315- cout << " [NOTE] asm file: " << flags.filePath (" asm " ) << " :183:1\n " ;
2321+ cout << " [NOTE] asm file: " << flags.filePath (" s " ) << " :183:1\n " ;
23162322 } else {
2317- removeFile (flags.filePath (" asm " ));
2323+ removeFile (flags.filePath (" s " ));
23182324 }
23192325 removeFile (flags.filePath (" obj" ));
23202326 if (flags.run ) return runCmdEchoed ({flags.filePathStr (" exe" )}, flags, false );
@@ -2330,7 +2336,7 @@ void run(Flags& flags) {
23302336 globalVm = VM ();
23312337 interpret ();
23322338 } else {
2333- ofstream outFile = openOutputFile (flags.filePath (" asm " ));
2339+ ofstream outFile = openOutputFile (flags.filePath (" s " ));
23342340 generate (outFile, parseCtx.instrs );
23352341
23362342 exitCode = compileAndRun (flags);
0 commit comments