disassembly

This commit is contained in:
julianb0 2019-05-16 21:42:23 +02:00
parent bb7730d3ce
commit 991cfeaf20
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
10 changed files with 175 additions and 71 deletions

2
.gitignore vendored
View File

@ -1,6 +1,8 @@
*.exe
*.out
*.bin
*.o
test*
arch_i.h
*.dis

View File

@ -1,7 +1,8 @@
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
all: kpc kas
all: kpc
# kas
kpc:
@cd pc && make --no-print-directory
@ -9,5 +10,6 @@ kpc:
kas:
@cd as && make --no-print-directory
test: all
test: kas
as/k-as.py as/testfile.asm as/testout.out

11
as/k-as.py Normal file → Executable file
View File

@ -3,5 +3,16 @@
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
import sys
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: {} input.asm output.bin".format(sys.argv[0]))
sys.exit(1)
fi = open(sys.argv[1], "r")
out = open(sys.argv[2], "wb")
out.close()
fi.close()

View File

@ -3,7 +3,7 @@
all: k.exe
src = instrs.c decd.c main.c regs.c dump.c jumps.c
src = instrs.c decd.c main.c regs.c dump.c jumps.c except.c disdec.c
obj = $(patsubst %.c,%.o,$(src))

View File

@ -111,6 +111,9 @@ struct ctx_t
// Read next instruction
ushort (*get)(ctx_t *ctx);
// For disassembly
FILE *disf;
};
enum
@ -130,25 +133,9 @@ void dumpinstr(ctx_t *, ulong, ushort, acc_t *, acc_t *);
void dumpmem(ctx_t *, ulong, ulong);
void dumpfwstack(ctx_t *);
static inline void _except(ctx_t *ctx, int code, char *fmt, ...)
{
va_list ap;
log("\nException %d - ", code);
va_start(ap, fmt);
vlog(fmt, ap);
va_end(ap);
log("\n");
dumpregs(ctx);
dumpfwstack(ctx);
free(ctx->mp);
exit(code+1);
}
void _except(ctx_t *, int, char *, ...);
void disasm(ctx_t *ctx);
void decode(ctx_t *ctx);
#define MEMOFF (1 * 1024 * 1024)

View File

@ -3,12 +3,33 @@
#include "arch.h"
void scan_param(ctx_t *ctx, acc_t *p)
#ifdef _NEED_DISASM
#define _except __except
static inline void _except(ctx_t *ctx, int x, char *fmt, ...)
{
va_list ap;
log("Disassembly error: ");
va_start(ap, fmt);
vlog(fmt, ap);
va_end(ap);
log("\n");
if (ctx->disf)
fclose(ctx->disf);
exit(-1);
}
#endif
static void scan_param(ctx_t *ctx, acc_t *p)
{
ushort c;
reg_t *r;
assert(p != 0);
c = ctx->get(ctx);
@ -25,7 +46,10 @@ void scan_param(ctx_t *ctx, acc_t *p)
}
if (c >= A_IMM16) {
assert(p->type == A_REG);
// Check for double access code
if (p->type != A_REG)
_except(ctx, E_ILL, "Bad access code");
p->type = c;
c = ctx->get(ctx);
}
@ -55,29 +79,26 @@ void scan_param(ctx_t *ctx, acc_t *p)
}
}
#ifndef _NEED_DISASM
void decode(ctx_t *ctx)
#else
void disasm(ctx_t *ctx)
#endif
{
instr_t *i;
acc_t p1 = { 0 }, p2 = { 0 };
ulong rip = ctx->r[RIP].val;
ushort c = ctx->get(ctx);
if (c == 0xFFFF) {
log("0x%016lX: stop\n", rip);
_except(ctx, E_SHT, "Shutdown INSTR");
}
else if (ISPREF(c)) {
if (ISPREF(c)) {
// nothing for now
}
else if (!ISINSTR(c)) {
_except(ctx, E_ILL, "Bad opcode 0x%4hX", c);
_except(ctx, E_ILL, "Bad opcode: 0x%4hX", c);
}
// Scanning an instruction
i = &ctx->i[c];
// Scan for parameters
@ -87,8 +108,11 @@ void decode(ctx_t *ctx)
scan_param(ctx, &p2);
}
}
dumpinstr(ctx, rip, c, &p1, &p2);
#ifndef _NEED_DISASM
i->func(ctx, &p1, &p2);
#endif
}

6
pc/disdec.c Normal file
View File

@ -0,0 +1,6 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#define _NEED_DISASM
#include "decd.c"

View File

@ -46,36 +46,53 @@ void dumpfwstack(ctx_t *ctx)
//dumpmem(ctx, FWSTACK - 128, 128 + 64);
}
void d_log(ctx_t *ctx, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (ctx->disf) {
vfprintf(ctx->disf, fmt, ap);
fflush(ctx->disf);
}
else
vlog(fmt, ap);
va_end(ap);
}
void dumpinstr(ctx_t *ctx, ulong rip, ushort c, acc_t *p1, acc_t *p2)
{
acc_t *p = 0;
instr_t *i = &ctx->i[c];
log("0x%016lX: %s", rip, i->name);
d_log(ctx, "0x%08lX: %s", rip, i->name);
if (i->prm1 != NOPRM)
p = p1;
lp:
if (p != 0) {
if (p->mem) log(" [");
else log(" ");
if (p->mem) d_log(ctx, " [");
else d_log(ctx, " ");
if (p->type == A_REG)
log("%s", ctx->r[p->val].name);
d_log(ctx, "%s", ctx->r[p->val].name);
else
log("0x%lX", p->val);
d_log(ctx, "0x%lX", p->val);
if (p->mem) {
if (p->off)
log("+%hd", p->off);
log("]");
d_log(ctx, "+%hd", p->off);
d_log(ctx, "]");
}
if (p == p1 && i->prm2 != NOPRM) {
p = p2;
log(",");
d_log(ctx, ",");
goto lp;
}
}
log("\n");
d_log(ctx, "\n");
}

25
pc/except.c Normal file
View File

@ -0,0 +1,25 @@
// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include "arch.h"
void _except(ctx_t *ctx, int code, char *fmt, ...)
{
va_list ap;
log("\nException %d - ", code);
va_start(ap, fmt);
vlog(fmt, ap);
va_end(ap);
log("\n");
dumpregs(ctx);
dumpfwstack(ctx);
if (ctx->mp)
free(ctx->mp);
exit(code+1);
}

View File

@ -14,18 +14,11 @@ ushort fwprog[] = {
I_ADD_R_I, RBX, A_IMM16, 1,
I_RET,
/*
I_MOV_M_I, A_MEM, RBP, A_IMM16, 0xAC,
I_SUB_R_I, RBP, A_IMM16, 8,
I_ADD_M_R, A_OFF, 8, RBP, RSP,
I_MOV_R_M, RAX, A_MEM, RBP,
*/
};
ushort bget(ctx_t *ctx)
{
if (addr2real(ctx->r[RIP].val) >= MEMSIZE) {
if (addr2real(ctx->r[RIP].val) >= ctx->mz) {
_except(ctx, E_ACC, "Executing out of memory: 0x%016lX",
ctx->r[RIP].val);
}
@ -37,35 +30,72 @@ ushort bget(ctx_t *ctx)
return c;
}
ushort dget(ctx_t *ctx)
{
static int i = 0;
if (i >= sizeof(fwprog)/2) {
log("Finished disassembling\n");
fclose(ctx->disf);
exit(0);
}
ctx->r[RIP].val += 2;
return fwprog[i++];
}
extern reg_t arch_r[NREGS];
extern instr_t arch_i[NINSTRS];
int main(void)
int main(int argc, char **argv)
{
static ctx_t main_ctx;
ctx_t main_ctx;
main_ctx.r = arch_r;
main_ctx.i = arch_i;
main_ctx.mp = malloc(MEMSIZE);
main_ctx.mz = MEMSIZE;
main_ctx.get = bget;
main_ctx.r[RIP].val = MEMOFF;
if (main_ctx.mp == 0) {
log("Couldn't allocate RAM");
exit(-1);
}
memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, sizeof(fwprog));
memset(&main_ctx.mp[addr2real(main_ctx.r[RIP].val) + sizeof(fwprog)/2], 0xFF, 0xFF);
while (1) {
decode(&main_ctx);
// Execute firmware
if (!(argc > 1 && !strcmp(argv[1], "-d"))) {
main_ctx.mp = malloc(MEMSIZE);
main_ctx.mz = MEMSIZE;
main_ctx.get = bget;
main_ctx.disf = NULL;
main_ctx.r[RIP].val = MEMOFF;
if (main_ctx.mp == 0) {
log("Couldn't allocate RAM\n");
exit(-1);
}
memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, sizeof(fwprog));
while (1) {
decode(&main_ctx);
}
}
// Disassembly
else {
main_ctx.disf = fopen("fwprog.dis", "w");
if (main_ctx.disf == NULL) {
log("Couldn't open fwprog.dis\n");
exit(-2);
}
main_ctx.mp = NULL;
main_ctx.mz = 0;
main_ctx.get = dget;
while (1) {
disasm(&main_ctx);
}
}
return 0;
}