mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
disassembly
This commit is contained in:
parent
bb7730d3ce
commit
991cfeaf20
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,8 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.bin
|
||||
*.o
|
||||
test*
|
||||
arch_i.h
|
||||
*.dis
|
||||
|
||||
|
6
Makefile
6
Makefile
@ -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
11
as/k-as.py
Normal file → Executable 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()
|
||||
|
||||
|
@ -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))
|
||||
|
||||
|
23
pc/arch.h
23
pc/arch.h
@ -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)
|
||||
|
52
pc/decd.c
52
pc/decd.c
@ -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
6
pc/disdec.c
Normal 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"
|
||||
|
35
pc/dump.c
35
pc/dump.c
@ -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
25
pc/except.c
Normal 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);
|
||||
}
|
||||
|
84
pc/main.c
84
pc/main.c
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user