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
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
|
*.bin
|
||||||
*.o
|
*.o
|
||||||
test*
|
test*
|
||||||
arch_i.h
|
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.
|
# The OS/K Team licenses this file to you under the MIT license.
|
||||||
# See the LICENSE file in the project root for more information.
|
# See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
all: kpc kas
|
all: kpc
|
||||||
|
# kas
|
||||||
|
|
||||||
kpc:
|
kpc:
|
||||||
@cd pc && make --no-print-directory
|
@cd pc && make --no-print-directory
|
||||||
@ -9,5 +10,6 @@ kpc:
|
|||||||
kas:
|
kas:
|
||||||
@cd as && make --no-print-directory
|
@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.
|
# The OS/K Team licenses this file to you under the MIT license.
|
||||||
# See the LICENSE file in the project root for more information.
|
# 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
|
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))
|
obj = $(patsubst %.c,%.o,$(src))
|
||||||
|
|
||||||
|
23
pc/arch.h
23
pc/arch.h
@ -111,6 +111,9 @@ struct ctx_t
|
|||||||
|
|
||||||
// Read next instruction
|
// Read next instruction
|
||||||
ushort (*get)(ctx_t *ctx);
|
ushort (*get)(ctx_t *ctx);
|
||||||
|
|
||||||
|
// For disassembly
|
||||||
|
FILE *disf;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -130,25 +133,9 @@ void dumpinstr(ctx_t *, ulong, ushort, acc_t *, acc_t *);
|
|||||||
void dumpmem(ctx_t *, ulong, ulong);
|
void dumpmem(ctx_t *, ulong, ulong);
|
||||||
void dumpfwstack(ctx_t *);
|
void dumpfwstack(ctx_t *);
|
||||||
|
|
||||||
static inline void _except(ctx_t *ctx, int code, char *fmt, ...)
|
void _except(ctx_t *, int, char *, ...);
|
||||||
{
|
|
||||||
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 disasm(ctx_t *ctx);
|
||||||
void decode(ctx_t *ctx);
|
void decode(ctx_t *ctx);
|
||||||
|
|
||||||
#define MEMOFF (1 * 1024 * 1024)
|
#define MEMOFF (1 * 1024 * 1024)
|
||||||
|
52
pc/decd.c
52
pc/decd.c
@ -3,12 +3,33 @@
|
|||||||
|
|
||||||
#include "arch.h"
|
#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;
|
ushort c;
|
||||||
reg_t *r;
|
reg_t *r;
|
||||||
|
|
||||||
assert(p != 0);
|
|
||||||
|
|
||||||
c = ctx->get(ctx);
|
c = ctx->get(ctx);
|
||||||
|
|
||||||
@ -25,7 +46,10 @@ void scan_param(ctx_t *ctx, acc_t *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (c >= A_IMM16) {
|
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;
|
p->type = c;
|
||||||
c = ctx->get(ctx);
|
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)
|
void decode(ctx_t *ctx)
|
||||||
|
#else
|
||||||
|
void disasm(ctx_t *ctx)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
instr_t *i;
|
instr_t *i;
|
||||||
acc_t p1 = { 0 }, p2 = { 0 };
|
acc_t p1 = { 0 }, p2 = { 0 };
|
||||||
|
|
||||||
ulong rip = ctx->r[RIP].val;
|
ulong rip = ctx->r[RIP].val;
|
||||||
ushort c = ctx->get(ctx);
|
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
|
// nothing for now
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!ISINSTR(c)) {
|
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];
|
i = &ctx->i[c];
|
||||||
|
|
||||||
// Scan for parameters
|
// Scan for parameters
|
||||||
@ -87,8 +108,11 @@ void decode(ctx_t *ctx)
|
|||||||
scan_param(ctx, &p2);
|
scan_param(ctx, &p2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dumpinstr(ctx, rip, c, &p1, &p2);
|
dumpinstr(ctx, rip, c, &p1, &p2);
|
||||||
|
|
||||||
|
#ifndef _NEED_DISASM
|
||||||
i->func(ctx, &p1, &p2);
|
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);
|
//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)
|
void dumpinstr(ctx_t *ctx, ulong rip, ushort c, acc_t *p1, acc_t *p2)
|
||||||
{
|
{
|
||||||
acc_t *p = 0;
|
acc_t *p = 0;
|
||||||
instr_t *i = &ctx->i[c];
|
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)
|
if (i->prm1 != NOPRM)
|
||||||
p = p1;
|
p = p1;
|
||||||
lp:
|
lp:
|
||||||
if (p != 0) {
|
if (p != 0) {
|
||||||
if (p->mem) log(" [");
|
if (p->mem) d_log(ctx, " [");
|
||||||
else log(" ");
|
else d_log(ctx, " ");
|
||||||
|
|
||||||
if (p->type == A_REG)
|
if (p->type == A_REG)
|
||||||
log("%s", ctx->r[p->val].name);
|
d_log(ctx, "%s", ctx->r[p->val].name);
|
||||||
else
|
else
|
||||||
log("0x%lX", p->val);
|
d_log(ctx, "0x%lX", p->val);
|
||||||
|
|
||||||
if (p->mem) {
|
if (p->mem) {
|
||||||
if (p->off)
|
if (p->off)
|
||||||
log("+%hd", p->off);
|
d_log(ctx, "+%hd", p->off);
|
||||||
log("]");
|
d_log(ctx, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == p1 && i->prm2 != NOPRM) {
|
if (p == p1 && i->prm2 != NOPRM) {
|
||||||
p = p2;
|
p = p2;
|
||||||
log(",");
|
d_log(ctx, ",");
|
||||||
goto lp;
|
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_ADD_R_I, RBX, A_IMM16, 1,
|
||||||
I_RET,
|
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)
|
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",
|
_except(ctx, E_ACC, "Executing out of memory: 0x%016lX",
|
||||||
ctx->r[RIP].val);
|
ctx->r[RIP].val);
|
||||||
}
|
}
|
||||||
@ -37,35 +30,72 @@ ushort bget(ctx_t *ctx)
|
|||||||
return c;
|
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 reg_t arch_r[NREGS];
|
||||||
extern instr_t arch_i[NINSTRS];
|
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.r = arch_r;
|
||||||
main_ctx.i = arch_i;
|
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) {
|
// Execute firmware
|
||||||
decode(&main_ctx);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user