im --TE BA im --nu cl jm :-ex ::TE 'd '1 '2 '6 \n // open input file im --IF JA zA IA im ##2. sy // open output file im --OF JA im ##241. IA im ##1ed. DA im ##2. sy // read next line ::rl im --LI RA rbp pointer to line buffer ::rL read loop im ##3. input file descriptor JA IR where to read into im ##1. DA read 1 byte im ##0. syscall 0 (read) sy // check how many bytes were read BA im ##1. jg if 1 greater than number of bytes read :-ef end of file BR DR pointer to character we just read im ##1. +B RA BD zA lb BA im ##a. jn :-rL keep looping // we now have a full line from the file in ::LI // the pointer to the end of the line is in rbp // look at the first character im --LI BA zA lb BA im ##3b. ascii ';' je if it's a comment, :-rl jump back to read the next line im ##a. ascii '\n' je if it's a blank line, :-rl jump back to read the next line im ##3a. ascii ':' je :-ld label definition jm :-ex // label definition ::ld // first, check if we're on the second pass. im --2P BA zA lb BA zA jn if on second pass, :-rl ignore this (read next line) // first get current address im ##4. output fd JA zA IA offset = 0 im ##1. whence = SEEK_CUR DA im ##8. syscall 8 = lseek sy BA im ##400000. address of start of file +B DA put current address in rdx im --L$ BA lq JA im --LI IA // copy from rsi to rdi until a newline is reached ::lc label copy BI zA lb BA // store in rdi AJ xc sb CA put byte in rcx // increment rdi,rsi BJ im ##1. +B JA BI im ##1. +B IA BC im ##a. jn if byte we read wasn't a newline, :-lc keep looping // store address of label in rdi AD BJ sd // increment rdi by 4, because we stored an 4-byte number im ##4. +B JA // now set L$ to rdi im --L$ BA AJ sq cc // // // exit with code in rax ::ex JA im ##3c. sy // convert string representation of number starting at rbx and ending with a newline to number in rax ::nu DB im ##1. +B IA start by storing pointer to actual number (not including base) in rsi BD zA lb BA im ##64. ascii 'd' je :-#d decimal im ##78. ascii 'x' je :-#x hexadecimal jm :-bn unrecognized number base // convert newline-terminated decimal representation in rsi to number in rax ::#d zA JA use rdi to store number ::dL decimal loop BI zA lb BA im ##a. je :-d$ newline reached im ##30. jg :-bn bad digit (<'0') im ##39. jl :-bn bad digit (>'9') im ##ffffffffffffffd0. +B CA put numerical value of digit in rcx im ##a. BA AJ +* multiply by 10 BC +B add digit JA // increment rsi BI im ##1. +B IA jm :-dL keep looping ::d$ AJ re return // convert ASCII hex digit in rbx to number in rax. ::hx im ##30. compare with ascii '0' jg :-bn bad if < '0' im ##39. jl :-af probably a-f im ##ffffffffffffffd0. -48 jm :-hX ::af im ##61. ASCII 'a' jg :-bn bad digit (not 0-9, and less than 'a') im ##66. ASCII 'f' jl :-bn bad digit (not 0-9, and greater than 'f') im ##ffffffffffffffa9. -87 (10 - 'a') ::hX +B re // return // bad number ::bn im ##2. stderr JA im --BN error message IA im ##a. length of error message DA im ##1. write sy im ##1. jm :-ex // end of file ::ef // TODO: second pass zA exit code 0 jm :-ex ::2P second pass? 00 ::IF input file name 'i 'n '0 '3 00 ::OF output file name 'o 'u 't '0 '3 00 ::BN bad number error message 'B 'a 'd 20 'n 'u 'm 'b 'e 'r \n ::LI line buffer ~~ ::L$ end of current label list --LB ::LB labels ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~