Skip to content

Commit 1e9175d

Browse files
First changes to gcc assembler
- # comments - '.'
1 parent 1344005 commit 1e9175d

File tree

1 file changed

+97
-91
lines changed

1 file changed

+97
-91
lines changed

Masfix.cpp

Lines changed: 97 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,121 +1950,123 @@ void genAssembly(ofstream& outFile, Instr instr, int instrNum) {
19501950

19511951
void 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
}
23052310
int 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

Comments
 (0)