diff --git a/Makefile b/Makefile index f86b627..1263ec0 100644 --- a/Makefile +++ b/Makefile @@ -7,14 +7,14 @@ all: kas kpc: @cd pc && make --no-print-directory -kas: kpc as/k-as.py as/regs.lst as/testfile.asm +kas: kpc as/k-as.py as/regs.lst as/testfile.k @cp pc/instrs/instrs.lst as @rm -f pc/instrs/instrs.lst test: kas - @cd as && ./k-as.py testfile.asm 0x100000 testout.out - @pc/k.exe as/testout.out + @cd as && ./k-as.py testfile.k 0x100000 testfile.out + @pc/k.exe as/testfile.out disasm: kas - @cd as && ./k-as.py testfile.asm 0x100000 testout.out - @pc/k.exe as/testout.out -d + @cd as && ./k-as.py testfile.k 0x100000 testfile.out + @pc/k.exe as/testfile.out -d diff --git a/as/k-as.py b/as/k-as.py index 92b32e2..7460dbe 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -13,9 +13,9 @@ if len(sys.argv) != 4: .format(sys.argv[0])) sys.exit(1) -instrs = open("{}.instr".format(sys.argv[3]), "w+") -b_data = open("{}.data".format(sys.argv[3]), "w+b") -b_text = open("{}.text".format(sys.argv[3]), "w+b") +instrs = open(".{}.instr".format(sys.argv[3]), "w+") +b_data = open(".{}.data".format(sys.argv[3]), "w+b") +b_text = open(".{}.text".format(sys.argv[3]), "w+b") lst_regs = open("regs.lst") lst_instrs = open("instrs.lst") diff --git a/as/k-as.py.text b/as/k-as.py.text deleted file mode 100644 index cdc4e1a..0000000 Binary files a/as/k-as.py.text and /dev/null differ diff --git a/as/testfile.asm b/as/testfile.k similarity index 85% rename from as/testfile.asm rename to as/testfile.k index 9f5de3b..03d06c4 100644 --- a/as/testfile.asm +++ b/as/testfile.k @@ -7,16 +7,16 @@ hw = 'Hello World' ; Entry point ; main: - ; This comment is successfully ignored + ; Initializes the stack mov rbp, 0x200000 mov rsp, rbp mov ax0, hw call print - - mov ax0, hw - mov ax1, hw_len - call print_n + +; mov ax0, hw +; mov ax1, hw_len +; call print_n stop diff --git a/pc/instrs/instrs.c b/pc/instrs/instrs.c index b98c014..61bd583 100644 --- a/pc/instrs/instrs.c +++ b/pc/instrs/instrs.c @@ -32,7 +32,9 @@ IMPL_OUT; IMPL_START_1(lea) { - assert(p2->mem); + if (!p2->mem) { + _except(ctx, E_ILL, "Bad LEA format"); + } v1 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val) + p2->off; } diff --git a/pc/instrs/instrs.h b/pc/instrs/instrs.h index ef42c07..5f16425 100644 --- a/pc/instrs/instrs.h +++ b/pc/instrs/instrs.h @@ -41,7 +41,7 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \ #define CHK_SUPERV() \ do { \ - if ((ctx->r[FLG].val & UF) == 1) { \ + if ((ctx->r[CR0].val & UF) == 1) { \ _except(ctx, E_SYS, "Supervisor-only INSTR"); \ } \ } while (0) diff --git a/pc/instrs/stack.c b/pc/instrs/stack.c index ee29bf2..d46dcc1 100644 --- a/pc/instrs/stack.c +++ b/pc/instrs/stack.c @@ -39,7 +39,9 @@ IMPL_END; IMPL_START_0(enter) { - CHK_STACK(<); + // We don't CHK_STACK(<) here because ENTER + // (should) always be preceded by a CALL, + // which already checks the stack PUSH(ctx->r[RBP].val); ctx->r[RBP].val = ctx->r[RSP].val; } @@ -47,7 +49,8 @@ IMPL_END; IMPL_START_0(leave) { - // Do NOT check stack here! + // Do NOT check stack here + // (it would always fail) POP(ctx->r[RBP].val); } IMPL_END; @@ -65,7 +68,8 @@ IMPL_START_0(popf) { CHK_STACK(<=); - CHK_SUPERV(); // XXX + // XXX + CHK_SUPERV(); ctx->r[RSP].val += 8; ctx->r[FLG].val = readmem64(ctx, ctx->r[RSP].val); diff --git a/pc/mem.c b/pc/mem.c index c5a6d62..d79b675 100644 --- a/pc/mem.c +++ b/pc/mem.c @@ -14,75 +14,6 @@ ulong readmem(ctx_t *ctx, ulong addr, uint len) } } -ulong readmem8(ctx_t *ctx, ulong addr) -{ - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr % 2 == 0) return (ulong)ctx->mp[real] & 0xFF; - else return ((ulong)ctx->mp[real] & 0xFF00) >> 8; -} - -ulong readmem16(ctx_t *ctx, ulong addr) -{ - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr % alignof(ushort) > 0) { - _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } - - return (ulong)ctx->mp[real]; -} - -ulong readmem32(ctx_t *ctx, ulong addr) -{ - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr % alignof(uint) > 0) { - _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } - - ulong val = ctx->mp[real++]; - val = val | ((ulong)ctx->mp[real] << 16); - - return val; -} - -ulong readmem64(ctx_t *ctx, ulong addr) -{ - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr % alignof(ulong) > 0) { - _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } - - ulong val = (ulong)ctx->mp[real++]; - val = val | ((ulong)ctx->mp[real++] << 16); - val = val | ((ulong)ctx->mp[real++] << 32); - val = val | ((ulong)ctx->mp[real] << 48); - - return val; -} - void writemem(ctx_t *ctx, ulong val, ulong addr, uint len) { addr += ctx->r[CR2].val; @@ -95,14 +26,71 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len) } } +#define CHK_RANGE() \ + if (addr < MEMOFF || real >= MEMSIZE) { \ + _except(ctx, E_ACC, \ + "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \ + } + +#define CHK_ALIGN(type) \ + if (addr % alignof(type) > 0) { \ + _except(ctx, E_ALI, \ + "Non-aligned memory access: 0x%012lX (0x%012lX) by %lu", \ + addr, real, alignof(type)); \ + } + +#define GETREAL() \ + addr += ctx->r[CR2].val; \ + ulong real = addr2real(addr) + +ulong readmem8(ctx_t *ctx, ulong addr) +{ + GETREAL(); + CHK_RANGE(); + + if (addr % 2 == 0) return (ulong)ctx->mp[real] & 0xFF; + else return ((ulong)ctx->mp[real] & 0xFF00) >> 8; +} + +ulong readmem16(ctx_t *ctx, ulong addr) +{ + GETREAL(); + CHK_RANGE(); + CHK_ALIGN(ushort); + + return (ulong)ctx->mp[real]; +} + +ulong readmem32(ctx_t *ctx, ulong addr) +{ + GETREAL(); + CHK_RANGE(); + CHK_ALIGN(uint); + + ulong val = ctx->mp[real++]; + val = val | ((ulong)ctx->mp[real] << 16); + + return val; +} + +ulong readmem64(ctx_t *ctx, ulong addr) +{ + GETREAL(); + CHK_RANGE(); + CHK_ALIGN(ulong); + + ulong val = (ulong)ctx->mp[real++]; + val = val | ((ulong)ctx->mp[real++] << 16); + val = val | ((ulong)ctx->mp[real++] << 32); + val = val | ((ulong)ctx->mp[real] << 48); + + return val; +} + void writemem8(ctx_t *ctx, ulong val, ulong addr) { - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } + GETREAL(); + CHK_RANGE(); ushort v = ctx->mp[real]; @@ -117,32 +105,18 @@ void writemem8(ctx_t *ctx, ulong val, ulong addr) void writemem16(ctx_t *ctx, ulong val, ulong addr) { - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr % alignof(ushort) > 0) { - _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } + GETREAL(); + CHK_RANGE(); + CHK_ALIGN(ushort); ctx->mp[real] = val & 0xFFFF; } void writemem32(ctx_t *ctx, ulong val, ulong addr) { - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr % alignof(uint) > 0) { - _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } + GETREAL(); + CHK_RANGE(); + CHK_ALIGN(uint); ctx->mp[real++] = val & 0xFFFF; ctx->mp[real] = (val >> 16) & 0xFFFF; @@ -150,16 +124,9 @@ void writemem32(ctx_t *ctx, ulong val, ulong addr) void writemem64(ctx_t *ctx, ulong val, ulong addr) { - addr += ctx->r[CR2].val; - ulong real = addr2real(addr); - - if (addr % alignof(ulong) > 0) { - _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX (0x%012lX)", addr, real); - } - - if (addr < MEMOFF || real >= MEMSIZE) { - _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); - } + GETREAL(); + CHK_RANGE(); + CHK_ALIGN(ulong); ctx->mp[real++] = val; ctx->mp[real++] = (val >> 16) & 0xFFFF;