From cc03cc87226d4ef68743a724486956154e429a1e Mon Sep 17 00:00:00 2001 From: julianb0 Date: Thu, 30 May 2019 11:19:16 +0200 Subject: [PATCH] stuff --- as/k-as.py | 143 ++++++++++++++++++++++++++++++++++------------------- os/dos.k | 21 +++----- pc/decd.c | 2 +- pc/regs.c | 13 +++-- 4 files changed, 110 insertions(+), 69 deletions(-) diff --git a/as/k-as.py b/as/k-as.py index 2db9496..c9d971d 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -56,6 +56,9 @@ pdata = 0 # size of .text section ptext = 0 +# for local labels +plastlabel = '' + # after parse() is done, pdata and ptext are never modified # padding bytes between .text and .data @@ -65,11 +68,19 @@ pdata_pad = 0 def name_valid(name): for c in name.lower(): - if not(c in 'abcdefghijklmnopqrstuvwxyz0123456789[$._+]='): + if not(c in 'abcdefghijklmnopqrstuvwxyz0123456789[$._+]=,'): print("BAD '{}'".format(c)) return False return True - + +def is_number(s): + try: + int(s, base=0) + + except ValueError: + return False + + return True #------------------------------------------------------------------------------- def parse_lst_regs(): @@ -148,22 +159,24 @@ def parse_preproc(line): #------------------------------------------------------------------------------- def apply_pdefs(line): - tok = line.split(' ') - new = '' + tok[0] + return line +""" + tok = line.split(' ', 1) - if len(tok) > 3: - print("Too many tokens in line: {}".format(line)) - return False, None - - # 'mov rax, rax' => 'mov rax rax' - if len(tok) == 3 and tok[1][-1] == ',': - tok[1] = tok[1][:-1] + instr = tok[0] + + new = '' + tok[0] for word in tok[1:]: + word = word.strip() new += ' ' - if word[0] == '[': + + print(word) + if '[' in word: + assert(len(word) > 2) assert(word[-1] == ']') - new += '[' + assert(word[1:].strip()[0] == '[') + new += word[0] + '[' word = word[1:-1] need_bracket = True else: @@ -174,43 +187,54 @@ def apply_pdefs(line): if not name_valid(word): print("Invalid token in line: {}".format(line)) - return False, None + leave() + sys.exit(1) + return None new += word if need_bracket: new += ']' - return True, new + return new +""" def parse(): global ptext + global plastlabel + for count, line in enumerate(fi): line = line.rstrip() - + if len(line) == 0: continue - - if line[0] == '#' or line[0] == ';': + + for i in range(len(line)): + if line[i] in '#;@!/': + line = line[:i].rstrip() + break + + if len(line) == 0: continue - + if line[0] == ' ' or line[0] == '\t': line = line.lstrip() - if line[0] in '#;@!/': - continue + line = apply_pdefs(line) + ptext += parse_instr(line) + instrs.write("\n") - ok, line = apply_pdefs(line) - if ok: - # instrs.write("{} ".format(ptext)) - ptext += parse_instr(line) - instrs.write("\n") continue # Preprocessor or label? if line[-1] == ':': if name_valid(line[:-1]): - plabels_text[line[:-1]] = ptext + label = line[:-1] + if label[0] == '.': + label = plastlabel + label + else: + plastlabel = label + plabels_text[label] = ptext else: print("Bad label name: {}".format(line[:-1])) leave() @@ -221,44 +245,53 @@ def parse(): parse_preproc(line) #------------------------------------------------------------------------------- - -def is_number(s): - try: - int(s, base=0) - - except ValueError: - return False - - return True def parse_instr(line): - # instrs.write(hex(ptext)) - tok = line.split(' ') + if line == None or len(line) == 0: + return 0 + + tok = line.split(' ', 1) + + instr = tok[0].strip() + + if len(tok) > 1: + params = tok[1].strip() + else: + params = None + fellthrough = False size = 2 - if tok[0] == "rep": + if instr == "rep": + if params == None: + print("Missing instruction after rep prefix: {}".format(line)) + leave() + sys.exit(1) + instrs.write("%rep ") - tok = tok[1:] + instr, params = params.split(' ', 1) size += 2 - instr_name = tok[0] + instr_name = instr instr_args = '' - if len(tok) == 1: + if params == None or len(params) == 0: instrs.write("{}".format(instr_name)) return 2 # instruction - tok = tok[1:] + tok = params.split(',') for word in tok: + word = word.strip() + instr_args += ' ' pref = None # memory length prefixes - if len(word) > 1 and word[1] == '[': + #print(word) + if len(word) > 2 and '[' in word: if word[0] == 'b': pref = "%b" elif word[0] == 'w': @@ -272,7 +305,8 @@ def parse_instr(line): leave() sys.exit(1) - word = word[1:] + word = word[1:].strip() + assert(word[0] == '[') # [reg+off] or [imm64] if word[0] == '[': @@ -294,13 +328,10 @@ def parse_instr(line): assert(len(word) > 3) - reg, off = word.strip().split('+', 1) + reg, off = word.split('+', 1) reg = reg.strip() off = off.strip() - print(reg) - print(off) - instr_args += "{} {}".format(off, reg) continue @@ -323,7 +354,13 @@ def parse_instr(line): instr_args += word fellthrough = False continue - + + # preprocessor + if word in pdefs: + word = pdefs[word] + # Fall through + + # register if word in pregs: size += 2 if not fellthrough: @@ -338,6 +375,10 @@ def parse_instr(line): if not fellthrough: instr_name += "_i" instr_args += "%imm64 " + + if word[0] == '.': + instr_args += plastlabel + instr_args += word fellthrough = False @@ -366,7 +407,7 @@ special_syms = { def gentext(): instrs.seek(0) - text_start = 0 # 0x100000 + text_start = 0x100000 data_start = text_start + ptext data_start += (8 - data_start % 8) diff --git a/os/dos.k b/os/dos.k index 13a30ad..c9a4a8a 100644 --- a/os/dos.k +++ b/os/dos.k @@ -3,8 +3,6 @@ hw = "Hello World" -; -; void main(void) ; ; Entry point ; @@ -15,6 +13,7 @@ main: mov ax0, hw call print + stop ; @@ -22,8 +21,6 @@ main: ; v_print_max := 0xFF -; -; void print(char *) ; ; Print a string ; @@ -31,19 +28,17 @@ print: enter mov rcx, v_print_max -.p1: - test b[ax0], b[ax0] - jz .p2 +.1: + test b[ax0], b [ ax0 + 0 ] + jz .2 prn b[ax0] inc ax0 - loop .p1 + loop .1 -.p2: +.2: leave ret -; -; void print_n(char *, int) ; ; Print exactly ax1 characters ; @@ -51,10 +46,10 @@ print_n: enter mov rcx, ax1 -.pn1: +.1: prn b[ax0] inc ax0 - loop .pn1 + loop .1 leave ret diff --git a/pc/decd.c b/pc/decd.c index 5641c8c..a3a88fc 100644 --- a/pc/decd.c +++ b/pc/decd.c @@ -122,9 +122,9 @@ void disasm(ctx_t *ctx) #else do_rep: + dumpinstr(ctx, rip, rep, c, &p1, &p2); i->func(ctx, &p1, &p2); - dumpinstr(ctx, rip, rep, c, &p1, &p2); if (rep && ctx->r[RCX].val > 0) { log("rcx::%lu\n", ctx->r[RCX].val); diff --git a/pc/regs.c b/pc/regs.c index b8a2071..b4e4a0f 100644 --- a/pc/regs.c +++ b/pc/regs.c @@ -10,9 +10,11 @@ reg_t arch_r[NREGS] = { "rip", "Instruction pointer", "Special; Volatile", 0, RES }, { "flg", "Flags register", "Special; Volatile", 0, RES }, + // Stack registers { "rbp", "Stack base", "Special; Non-volatile", 0, GPR }, { "rsp", "Stack pointer", "Special; Non-volatile", 0, GPR }, + // General-purpose volatile registers { "rax", "Accumulator 0", "Volatile", 0, GPR }, { "rbx", "Accumulator 1", "Volatile", 0, GPR }, { "rcx", "Accumulator 2", "Volatile", 0, GPR }, @@ -22,6 +24,7 @@ reg_t arch_r[NREGS] = { "rdi", "Accumulator 6", "Volatile", 0, GPR }, { "rsi", "Accumulator 7", "Volatile", 0, GPR }, + // General-purpose non-volatile registers { "nx0", "Accumulator 8", "Non-volatile", 0, GPR }, { "nx1", "Accumulator 9", "Non-volatile", 0, GPR }, { "nx2", "Accumulator 10", "Non-volatile", 0, GPR }, @@ -30,7 +33,8 @@ reg_t arch_r[NREGS] = { "nx5", "Accumulator 13", "Non-volatile", 0, GPR }, { "nx6", "Accumulator 14", "Non-volatile", 0, GPR }, { "nx7", "Accumulator 15", "Non-volatile", 0, GPR }, - + + // Argument registers; volatile { "ax0", "Argument 0", "Volatile", 0, GPR }, { "ax1", "Argument 1", "Volatile", 0, GPR }, { "ax2", "Argument 2", "Volatile", 0, GPR }, @@ -44,18 +48,19 @@ reg_t arch_r[NREGS] = { "cr0", "Control register 0", "Control", 0, CTL }, // cr1: code offset - { "cr1", "Control register 1", "Control", 0x100000, CTL }, + { "cr1", "Control register 1", "Control", 0, CTL }, // cr2: data offset - { "cr2", "Control register 2", "Control", 0x100000, CTL }, + { "cr2", "Control register 2", "Control", 0, CTL }, - // unused + // Unused { "cr3", "Control register 3", "Control", 0, CTL }, { "cr4", "Control register 4", "Control", 0, CTL }, { "cr5", "Control register 5", "Control", 0, CTL }, { "cr6", "Control register 6", "Control", 0, CTL }, { "cr7", "Control register 7", "Control", 0, CTL }, + // System-reserved { "sa0", "Supervisor acc. 0", "System; Non-volatile", 0, SYS }, { "sa1", "Supervisor acc. 1", "System; Non-volatile", 0, SYS }, { "sa2", "Supervisor acc. 2", "System; Non-volatile", 0, SYS },