From bb21e15dc48a01cca1cb1d23d9beb01109320f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Mon, 8 Oct 2018 21:50:40 +0200 Subject: [PATCH] feat: ajout de fonction v/s/printf et ajout de fonction de deboguage (desassemblage) --- include/debug.h | 37 + include/shell.h | 1 + include/video.h | 7 +- lib/debug.c | 2562 +++++++++++++++++++++++++++++++++++++++++++++++ lib/shell.c | 97 +- lib/vga.c | 10 +- lib/video.c | 47 +- 7 files changed, 2735 insertions(+), 26 deletions(-) create mode 100644 include/debug.h create mode 100644 lib/debug.c diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 0000000..a9a1967 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,37 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ +#include "types.h" + +#define opBufSz 32 + +#define decodeSIB() \ + base = r32[*b&0x07]; \ + indx = r32[(*b&0x38)>>3]; \ + scale = ((*b&0xc0)>>6)*2; \ + if(scale && !indx){ \ + print("Invalid SIB byte."); \ + return; \ + } + +#define setG() \ + reg = (*b&0x38)>>3; \ + if(!Gsz){ \ + } else if(Gsz == 1){ \ + G = r8[reg]; \ + } else if(Gsz == 2){ \ + G = r16[reg]; \ + } else if(Gsz == 3){ \ + G = r32[reg]; \ + } else if(Gsz == 4){ \ + if(reg < 8){ \ + G = rseg[reg]; \ + } else{ \ + print("Invalid Mod R/M byte."); \ + return; \ + } \ + } else{ \ + print("Invalid Mod R/M byte."); \ + return; \ + } + diff --git a/include/shell.h b/include/shell.h index d310260..441a1c9 100644 --- a/include/shell.h +++ b/include/shell.h @@ -20,3 +20,4 @@ int info(); int err(); int view(); int test(void); +int disasm(u8* commandline); diff --git a/include/video.h b/include/video.h index 9396755..36b5509 100755 --- a/include/video.h +++ b/include/video.h @@ -21,9 +21,14 @@ void putchar(u8 thechar); void clearscreen(void); u32 print(u8* string); u32 printf (const u8 *string, ...); +u32 sprintf(u8 *variable, const u8 *string, ...); +u32 snprintf(u8 *variable, u32 maxsize, const u8 *string, ...); +u32 vprintf(const u8 * string, va_list args); +u32 vsprintf(u8 *variable, const u8 *string, va_list args); +u32 vsnprintf(u8 *variable, u32 maxsize, const u8 *string, va_list args); void changevc(u8 vc); u8* itoa(u64 num, u8* str, u8 base, u64 dim, u8 achar); u8* sitoa(u64 num, u8 * str, u64 dim); u8* rtoadouble(double num, u8 * str, u8 precisioni , u8 precisionf); u8* rtoasingle(float num, u8 * str, u8 precisioni , u8 precisionf); -u32 format(const u8 * string, va_list args, u32 (*fonction)(u8* src, u8** dest, u32 len), u8* dest); +u32 format(const u8 * string, va_list args, u32 maxsize, u32 (*fonction)(u8* src, u8** dest, u32 len), u8* dest); diff --git a/lib/debug.c b/lib/debug.c new file mode 100644 index 0000000..9aab7df --- /dev/null +++ b/lib/debug.c @@ -0,0 +1,2562 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ +#include "types.h" +#include "video.h" +#include "debug.h" + +u8 *f_entry; +u16 entry; +u8 *r8[] = {"al","cl","dl","bl","ah","ch","dh","bh"}; +u8 *r16[] = {"ax","cx","dx","bx","sp","bp","si","di"}; +u8 *r32[] = {"eax","ecx","edx","ebx","esp","ebp","esi","edi"}; +u8 *rseg[] = {"ds","es","fs","gs","ss","cs","ip"}; + + +u16 decodeModSM(u8 *a, u8 *op, u16 order, u32 Gsz, u32 Esz){ + u32 len = 0; + u32 reg = 0; + u32 scale = 0; + u8 *b = a; + u8 *E, *G, *indx, *base, *disp = "\0"; + u8 ebuf[32] = {0}; + + setG(); + + if(Esz){ + switch(*b&0xc7){ + case 0x00: + E = "[bx+si]"; + break; + case 0x01: + E = "[bx+di]"; + break; + case 0x02: + E = "[bp+si]"; + break; + case 0x03: + E = "[bp+di]"; + break; + case 0x04: + E = "[si]"; + break; + case 0x05: + E = "[di]"; + break; + case 0x06: + snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x07: + E = "[bx]"; + break; + case 0x40: + snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x41: + snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x42: + snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x43: + snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x44: + snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x45: + snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x46: + snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x47: + snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); + E = ebuf; + case 0x80: + snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x81: + snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x82: + snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x83: + snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x84: + snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x85: + snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x86: + snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0x87: + snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); + E = ebuf; + ++b; + break; + case 0xc0: + E = "al"; + break; + case 0xc1: + E = "cl"; + break; + case 0xc2: + E = "dl"; + break; + case 0xc3: + E = "bl"; + break; + case 0xc4: + E = "ah"; + break; + case 0xc5: + E = "ch"; + break; + case 0xc6: + E = "dh"; + break; + case 0xc7: + E = "bh"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } else{ + switch(*b & 0xc7){ + case 0x00: + E = "[eax]"; + break; + case 0x01: + E = "[ecx]"; + break; + case 0x02: + E = "[edx]"; + break; + case 0x03: + E = "[ebx]"; + break; + case 0x04: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s]", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s]", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i]", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s]", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i]", base, indx, scale); + } + E = ebuf; + break; + case 0x05: + snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x06: + E = "[esi]"; + break; + case 0x07: + E = "[edi]"; + break; + case 0x40: + snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x41: + snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x42: + snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x43: + snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u8 *)++b); + E = ebuf; + case 0x44: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); + } + len = strlen(ebuf); + snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x45: + snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x46: + snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x47: + snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x80: + snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x81: + snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u32 *)++b); + E = ebuf; + break; + case 0x82: + snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x83: + snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x84: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); + } + len = strlen(ebuf); + snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u32 *)++b); + b += 3; + E = ebuf; + break; + case 0x85: + snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x86: + snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x87: + snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0xc0: + E = Esz == 1 ? "ax": "eax"; + break; + case 0xc1: + E = Esz == 1 ? "cx": "ecx"; + break; + case 0xc2: + E = Esz == 1 ? "dx": "edx"; + break; + case 0xc3: + E = Esz == 1 ? "bx": "ebx"; + break; + case 0xc4: + E = Esz == 1 ? "sp": "esp"; + break; + case 0xc5: + E = Esz == 1 ? "bp": "ebp"; + break; + case 0xc6: + E = Esz == 1 ? "si": "esi"; + break; + case 0xc7: + E = Esz == 1 ? "di": "edi"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } + + if(order){ + snprintf(op, opBufSz, "%s", E); + len = strlen(op); + if(Gsz){ + snprintf(op+len, opBufSz-len, ", %s", G); + } + } else{ + snprintf(op, opBufSz, "%s, ", G); + len = strlen(op); + snprintf(op+len, opBufSz-len, "%s", E); + } + return b-a; +} + +u32 decodeModSM_float(u8 *a, u8 *op, u32 order, u32 Gsz, u32 Esz){ + u32 len = 0; + u32 reg = 0; + u32 scale = 0; + u8 *b = a; + u8 *E, *G, *indx, *base, *disp = "\0"; + u8 ebuf[32] = {0}; + + setG(); + + if(Esz){ + switch(*b&0xc7){ + case 0x00: + E = "[bx+si]"; + break; + case 0x01: + E = "[bx+di]"; + break; + case 0x02: + E = "[bp+si]"; + break; + case 0x03: + E = "[bp+di]"; + break; + case 0x04: + E = "[si]"; + break; + case 0x05: + E = "[di]"; + break; + case 0x06: + snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x07: + E = "[bx]"; + break; + case 0x40: + snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x41: + snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x42: + snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x43: + snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x44: + snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x45: + snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x46: + snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x47: + snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); + E = ebuf; + case 0x80: + snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x81: + snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x82: + snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x83: + snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x84: + snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x85: + snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x86: + snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x87: + snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0xc0: + E = "st(0)"; + break; + case 0xc1: + E = "st(1)"; + break; + case 0xc2: + E = "st(2)"; + break; + case 0xc3: + E = "st(3)"; + break; + case 0xc4: + E = "st(4)"; + break; + case 0xc5: + E = "st(5)"; + break; + case 0xc6: + E = "st(6)"; + break; + case 0xc7: + E = "st(7)"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } else{ + switch(*b & 0xc7){ + case 0x00: + E = "[eax]"; + break; + case 0x01: + E = "[ecx]"; + break; + case 0x02: + E = "[edx]"; + break; + case 0x03: + E = "[ebx]"; + break; + case 0x04: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s]", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s]", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i]", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s]", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i]", base, indx, scale); + } + E = ebuf; + break; + case 0x05: + snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x06: + E = "[esi]"; + break; + case 0x07: + E = "[edi]"; + break; + case 0x40: + snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x41: + snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x42: + snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x43: + snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u8 *)++b); + E = ebuf; + case 0x44: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); + } + len = strlen(ebuf); + snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x45: + snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x46: + snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x47: + snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x80: + snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x81: + snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u32 *)++b); + E = ebuf; + break; + case 0x82: + snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x83: + snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x84: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); + } + len = strlen(ebuf); + snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u32 *)++b); + b += 3; + E = ebuf; + break; + case 0x85: + snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x86: + snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x87: + snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0xc0: + E = "st(0)"; + break; + case 0xc1: + E = "st(1)"; + break; + case 0xc2: + E = "st(2)"; + break; + case 0xc3: + E = "st(3)"; + break; + case 0xc4: + E = "st(4)"; + break; + case 0xc5: + E = "st(5)"; + break; + case 0xc6: + E = "st(6)"; + break; + case 0xc7: + E = "st(7)"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } + + if(order){ + snprintf(op, opBufSz, "%s", E); + len = strlen(op); + if(Gsz){ + snprintf(op+len, opBufSz-len, ", %s", G); + } + } else{ + snprintf(op, opBufSz, "%s, ", G); + len = strlen(op); + snprintf(op+len, opBufSz-len, "%s", E); + } + return b-a; +} + +u32 decodeModSM_memonly(u8 *a, u8 *op, u32 order, u32 Gsz, u32 Esz){ + u32 len = 0; + u32 reg = 0; + u32 scale = 0; + u8 *b = a; + u8 *E, *G, *indx, *base, *disp = "\0"; + u8 ebuf[32] = {0}; + + setG(); + + if(Esz){ + switch(*b&0xc7){ + case 0x00: + E = "[bx+si]"; + break; + case 0x01: + E = "[bx+di]"; + break; + case 0x02: + E = "[bp+si]"; + break; + case 0x03: + E = "[bp+di]"; + break; + case 0x04: + E = "[si]"; + break; + case 0x05: + E = "[di]"; + break; + case 0x06: + snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x07: + E = "[bx]"; + break; + case 0x40: + snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x41: + snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x42: + snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x43: + snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x44: + snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x45: + snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x46: + snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x47: + snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u8 *)++b); + E = ebuf; + case 0x80: + snprintf(ebuf, sizeof(ebuf), "[bx+si+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x81: + snprintf(ebuf, sizeof(ebuf), "[bx+di+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x82: + snprintf(ebuf, sizeof(ebuf), "[bp+si+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x83: + snprintf(ebuf, sizeof(ebuf), "[bp+di+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x84: + snprintf(ebuf, sizeof(ebuf), "[si+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x85: + snprintf(ebuf, sizeof(ebuf), "[di+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x86: + snprintf(ebuf, sizeof(ebuf), "[bp+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + case 0x87: + snprintf(ebuf, sizeof(ebuf), "[bx+%x]", *(u16 *)++b); + E = ebuf; + ++b; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } else{ + switch(*b&0xc7){ + case 0x00: + E = "[eax]"; + break; + case 0x01: + E = "[ecx]"; + break; + case 0x02: + E = "[edx]"; + break; + case 0x03: + E = "[ebx]"; + break; + case 0x04: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s]", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s]", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i]", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s]", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i]", base, indx, scale); + } + E = ebuf; + break; + case 0x05: + snprintf(ebuf, sizeof(ebuf), "ds:%x", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x06: + E = "[esi]"; + break; + case 0x07: + E = "[edi]"; + break; + case 0x40: + snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x41: + snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x42: + snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x43: + snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u8 *)++b); + E = ebuf; + case 0x44: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); + } + len = strlen(ebuf); + snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x45: + snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x46: + snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x47: + snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u8 *)++b); + E = ebuf; + break; + case 0x80: + snprintf(ebuf, sizeof(ebuf), "[eax+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x81: + snprintf(ebuf, sizeof(ebuf), "[ecx+%x]", *(u32 *)++b); + E = ebuf; + break; + case 0x82: + snprintf(ebuf, sizeof(ebuf), "[edx+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x83: + snprintf(ebuf, sizeof(ebuf), "[ebx+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x84: + ++b; + decodeSIB(); + if(!indx){ + snprintf(ebuf, sizeof(ebuf), "[%s", base); + } else if(!base){ + if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s", indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s*%i", indx, scale); + } + } else if(!scale){ + snprintf(ebuf, sizeof(ebuf), "[%s+%s", base, indx); + } else{ + snprintf(ebuf, sizeof(ebuf), "[%s+%s*%i", base, indx, scale); + } + len = strlen(ebuf); + snprintf(ebuf+len, sizeof(ebuf)-len, "+%x]", *(u32 *)++b); + b += 3; + E = ebuf; + break; + case 0x85: + snprintf(ebuf, sizeof(ebuf), "[ebp+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x86: + snprintf(ebuf, sizeof(ebuf), "[esi+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + case 0x87: + snprintf(ebuf, sizeof(ebuf), "[edi+%x]", *(u32 *)++b); + E = ebuf; + b += 3; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } + + if(order){ + snprintf(op, opBufSz, "%s", E); + len = strlen(op); + if(Gsz){ + snprintf(op+len, opBufSz-len, ", %s", G); + } + } else{ + snprintf(op, opBufSz, "%s, ", G); + len = strlen(op); + snprintf(op+len, opBufSz-len, "%s", E); + } + return b-a; +} + +u32 decode(u8 *a){ + u8 *b = a; + u32 len = 0; + u32 flip_addr_sz = 0; + u32 flip_imm_sz = 0; + u32 EG = 1; + u32 B = 1; + u8 *s, *prefix, *seg_oride = "\0"; + u8 op1[opBufSz] = {0}; + + if(*b == 0xf3){ + prefix = "rep"; + ++b; + } else if(*b == 0xf2){ + prefix = "repnz"; + ++b; + } else if(*b == 0xf0){ + prefix = "lock"; + ++b; + } + + if(*b == 0x67){ + flip_addr_sz = 1; + ++b; + } + if (*b == 0x66){ + flip_imm_sz = 1; + ++b; + } + + switch(*b){ + case 0x2e: + seg_oride = "cs"; + ++b; + break; + case 0x36: + seg_oride = "ss"; + ++b; + break; + case 0x3e: + seg_oride = "ds"; + ++b; + break; + case 0x26: + seg_oride = "es"; + ++b; + break; + case 0x64: + seg_oride = "fs"; + ++b; + break; + case 0x65: + seg_oride = "gs"; + ++b; + } + + if(*b == 0x0f){ + + print("Extended opcodes not implimented.\r\n"); + return; + + } else{ + + switch(*b){ + case 0x00: + s = "add"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x01: + s = "add"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x02: + s = "add"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x03: + s = "add"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x04: + s = "add"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x05: + s = "add"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x06: + s = "push es"; + break; + case 0x07: + s = "pop es"; + break; + case 0x08: + s = "or"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x09: + s = "or"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x0a: + s = "or"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x0b: + s = "or"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x0c: + s = "or"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x0d: + s = "or"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x0e: + s = "push cs"; + break; + case 0x10: + s = "adc"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x11: + s = "adc"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x12: + s = "adc"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x13: + s = "adc"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x14: + s = "adc"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x15: + s = "adc"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x16: + s = "push ss"; + break; + case 0x17: + s = "pop ss"; + break; + case 0x18: + s = "sbb"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x19: + s = "sbb"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x1a: + s = "sbb"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x1b: + s = "sbb"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x1c: + s = "sbb"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x1d: + s = "sbb"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x1e: + s = "push ds"; + break; + case 0x1f: + s = "pop ds"; + break; + case 0x20: + s = "and"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x21: + s = "and"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x22: + s = "and"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x23: + s = "and"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x24: + s = "and"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x25: + s = "and"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x27: + s = "daa"; + break; + case 0x28: + s = "sub"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x29: + s = "sub"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x2a: + s = "sub"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x2b: + s = "sub"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x2c: + s = "sub"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x2d: + s = "sub"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x2f: + s = "das"; + break; + case 0x30: + s = "xor"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x31: + s = "xor"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x32: + s = "xor"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x33: + s = "xor"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x34: + s = "xor"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x35: + s = "xor"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x37: + s = "aaa"; + break; + case 0x38: + s = "cmp"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x39: + s = "cmp"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x3a: + s = "cmp"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x3b: + s = "cmp"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x3c: + s = "cmp"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0x3d: + s = "cmp"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0x3f: + s = "aas"; + break; + case 0x40: + s = flip_imm_sz ? "inc ax": "inc eax"; + break; + case 0x41: + s = flip_imm_sz ? "inc cx": "inc ecx"; + break; + case 0x42: + s = flip_imm_sz ? "inc dx": "inc edx"; + break; + case 0x43: + s = flip_imm_sz ? "inc bx": "inc ebx"; + break; + case 0x44: + s = flip_imm_sz ? "inc sp": "inc esp"; + break; + case 0x45: + s = flip_imm_sz ? "inc bp": "inc ebp"; + break; + case 0x46: + s = flip_imm_sz ? "inc si": "inc esi"; + break; + case 0x47: + s = flip_imm_sz ? "inc di": "inc edi"; + break; + case 0x48: + s = flip_imm_sz ? "dec ax": "dec eax"; + break; + case 0x49: + s = flip_imm_sz ? "dec cx": "dec ecx"; + break; + case 0x4a: + s = flip_imm_sz ? "dec dx": "dec edx"; + break; + case 0x4b: + s = flip_imm_sz ? "dec bx": "dec ebx"; + break; + case 0x4c: + s = flip_imm_sz ? "dec sp": "dec esp"; + break; + case 0x4d: + s = flip_imm_sz ? "dec bp": "dec ebp"; + break; + case 0x4e: + s = flip_imm_sz ? "dec si": "dec esi"; + break; + case 0x4f: + s = flip_imm_sz ? "dec di": "dec edi"; + break; + case 0x50: + s = flip_imm_sz ? "push ax": "push eax"; + break; + case 0x51: + s = flip_imm_sz ? "push cx": "push ecx"; + break; + case 0x52: + s = flip_imm_sz ? "push dx": "push edx"; + break; + case 0x53: + s = flip_imm_sz ? "push bx": "push ebx"; + break; + case 0x54: + s = flip_imm_sz ? "push sp": "push esp"; + break; + case 0x55: + s = flip_imm_sz ? "push bp": "push ebp"; + break; + case 0x56: + s = flip_imm_sz ? "push si": "push esi"; + break; + case 0x57: + s = flip_imm_sz ? "push di": "push edi"; + break; + case 0x58: + s = flip_imm_sz ? "pop ax": "pop eax"; + break; + case 0x59: + s = flip_imm_sz ? "pop cx": "pop ecx"; + break; + case 0x5a: + s = flip_imm_sz ? "pop dx": "pop edx"; + break; + case 0x5b: + s = flip_imm_sz ? "pop bx": "pop ebx"; + break; + case 0x5c: + s = flip_imm_sz ? "pop sp": "pop esp"; + break; + case 0x5d: + s = flip_imm_sz ? "pop bp": "pop ebp"; + break; + case 0x5e: + s = flip_imm_sz ? "pop si": "pop esi"; + break; + case 0x5f: + s = flip_imm_sz ? "pop di": "pop edi"; + break; + case 0x60: + s = flip_imm_sz ? "pushaw": "pusha"; + break; + case 0x61: + s = flip_imm_sz ? "popaw": "popa"; + break; + case 0x63: + s = "arpl"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x68: + s = "push"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "%x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "%x", *(u32 *)++b); + b += 3; + } + break; + case 0x69: + s = "imul"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + len = strlen(op1); + if(flip_imm_sz){ + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u32 *)++b); + b += 3; + } + break; + case 0x6a: + s = "push"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)*b); + case 0x6b: + s = "imul"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0x6c: + s = flip_addr_sz ? "ins bytes ptr es:[di], dx": "insb"; + break; + case 0x6d: + if(flip_addr_sz){ + s = flip_imm_sz ? "ins word ptr es:[di], dx": "ins dword ptr es:[di], dx"; + } else{ + s = flip_imm_sz ? "insw": "insd"; + } + break; + case 0x6e: + s = flip_addr_sz ? "outs dx, byte ptr [si]": "outsb"; + break; + case 0x6f: + if(flip_addr_sz){ + s = flip_imm_sz ? "outs dx, word ptr [si]": "outs dx, dword ptr [si]"; + } else{ + s = flip_imm_sz ? "outsw": "outsd"; + } + break; + case 0x70: + s = "jo"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x71: + s = "jno"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x72: + s = "jb"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x73: + s = "jnb"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x74: + s = "jz"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x75: + s = "jnz"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x76: + s = "jbe"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x77: + s = "ja"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x78: + s = "js"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x79: + s = "jns"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x7a: + s = "jp"; + ++b; + break; + case 0x7b: + s = "jnp"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x7c: + s = "jl"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x7d: + s = "jnl"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x7e: + s = "jle"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x7f: + s = "jnle"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0x80: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "add"; + break; + case 1: + s = "or"; + break; + case 2: + s = "adc"; + break; + case 3: + s = "sbb"; + break; + case 4: + s = "and"; + break; + case 5: + s = "sub"; + break; + case 6: + s = "xor"; + break; + case 7: + s = "cmp"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0x81: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "add"; + break; + case 1: + s = "or"; + break; + case 2: + s = "adc"; + break; + case 3: + s = "sbb"; + break; + case 4: + s = "and"; + break; + case 5: + s = "sub"; + break; + case 6: + s = "xor"; + break; + case 7: + s = "cmp"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + if(flip_imm_sz){ + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u32 *)++b); + b += 3; + } + break; + case 0x82: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "add"; + break; + case 1: + s = "or"; + break; + case 2: + s = "adc"; + break; + case 3: + s = "sbb"; + break; + case 4: + s = "and"; + break; + case 5: + s = "sub"; + break; + case 6: + s = "xor"; + break; + case 7: + s = "cmp"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0x83: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "add"; + break; + case 1: + s = "or"; + break; + case 2: + s = "adc"; + break; + case 3: + s = "sbb"; + break; + case 4: + s = "and"; + break; + case 5: + s = "sub"; + break; + case 6: + s = "xor"; + break; + case 7: + s = "cmp"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0x84: + s = "test"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x85: + s = "test"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x86: + s = "xchg"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x87: + s = "xchg"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x88: + s = "mov"; + b += decodeModSM(++b, op1, 1, 1, flip_addr_sz); + break; + case 0x89: + s = "mov"; + b += decodeModSM(++b, op1, 1, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x8a: + s = "mov"; + b += decodeModSM(++b, op1, 0, 1, flip_addr_sz); + break; + case 0x8b: + s = "mov"; + b += decodeModSM(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x8c: + s = "mov"; + b += decodeModSM(++b, op1, 1, 4, flip_addr_sz); + break; + case 0x8d: + s = "lea"; + b += decodeModSM_memonly(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0x8e: + s = "mov"; + b += decodeModSM(++b, op1, 0, 4, flip_addr_sz); + break; + case 0x8f: + s = "pop"; + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + break; + case 0x90: + s = flip_imm_sz ? "xchg ax, ax": "nop"; + break; + case 0x91: + s = flip_imm_sz ? "xchg ax, cx": "xchg eax, ecx"; + break; + case 0x92: + s = flip_imm_sz ? "xchg ax, dx": "xchg eax, edx"; + break; + case 0x93: + s = flip_imm_sz ? "xchg ax, bx": "xchg eax, ebx"; + break; + case 0x94: + s = flip_imm_sz ? "xchg ax, sp": "xchg eax, esp"; + break; + case 0x95: + s = flip_imm_sz ? "xchg ax, bp": "xchg eax, ebp"; + break; + case 0x96: + s = flip_imm_sz ? "xchg ax, si": "xchg eax, esi"; + break; + case 0x97: + s = flip_imm_sz ? "xchg ax, di": "xchg eax, edi"; + break; + case 0x98: + s = flip_imm_sz ? "cbw": "cwde"; + break; + case 0x99: + s = flip_imm_sz ? "cwd": "cdq"; + break; + case 0x9a: + s = "call"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "%x:%x", *(u16 *)(b+2), *(u16 *)++b); + b += 3; + } else{ + snprintf(op1, sizeof(op1), "far ptr %x:%x", *(u16 *)(b+4), *(u32 *)++b); + b += 5; + } + break; + case 0x9b: + s = "wait"; + break; + case 0x9c: + s = flip_imm_sz ? "pushfw": "pushf"; + break; + case 0x9d: + s = flip_imm_sz ? "popfw": "popf"; + break; + case 0x9e: + s = "sahf"; + break; + case 0x9f: + s = "lahf"; + break; + case 0xa0: + s = "mov"; + snprintf(op1, sizeof(op1), "al, ds:%x", *(u32 *)++b); + b += 3; + break; + case 0xa1: + s = "mov"; + snprintf(op1, sizeof(op1), flip_imm_sz ? "ax, ds:%x": "eax, ds:%x", *(u32 *)++b); + b += 3; + break; + case 0xa2: + s = "mov"; + snprintf(op1, sizeof(op1), "ds:%x, al", *(u32 *)++b); + b += 3; + break; + case 0xa3: + s = "mov"; + snprintf(op1, sizeof(op1), flip_imm_sz ? "ds:%x, ax": "ds:%x, eax", *(u32 *)++b); + b += 3; + break; + case 0xa4: + s = flip_addr_sz ? "movs byte ptr es:[di], byte ptr [si]": "movsb"; + break; + case 0xa5: + if(flip_addr_sz){ + s = flip_imm_sz ? "movs word ptr es:[di], word ptr [si]": "movs dword ptr es:[di], dword ptr [si]"; + } else{ + s = flip_imm_sz ? "movsw": "movsd"; + } + break; + case 0xa6: + s = flip_addr_sz ? "cmps byte ptr [si], byte ptr es:[di]": "cmpsb"; + break; + case 0xa7: + if(flip_addr_sz){ + s = flip_imm_sz ? "movs word ptr [si], word ptr es:[di]": "movs dword ptr [si], dword ptr es:[di]"; + } else{ + s = flip_imm_sz ? "cmpsw": "cmpsd"; + } + break; + case 0xa8: + s = "test"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0xa9: + s = "test"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + b += 3; + } + break; + case 0xaa: + s = flip_addr_sz ? "stos byte ptr es:[di]": "stosb"; + break; + case 0xab: + if(flip_addr_sz){ + s = flip_imm_sz ? "stos word ptr es:[di]": "stos dword ptr es:[di]"; + } else{ + s = flip_imm_sz ? "stosw": "stosd"; + } + break; + case 0xac: + s = flip_addr_sz ? "lods byte ptr [si]": "lodsb"; + break; + case 0xad: + if(flip_addr_sz){ + s = flip_imm_sz ? "lods word ptr [si]": "lods dword ptr [si]"; + } else{ + s = flip_imm_sz ? "lodsw": "lodsd"; + } + break; + case 0xae: + s = flip_addr_sz ? "scas byte ptr es:[di]": "scasb"; + break; + case 0xaf: + if(flip_addr_sz){ + s = flip_imm_sz ? "scas word ptr es:[di]": "scas dword ptr es:[di]"; + } else{ + s = flip_imm_sz ? "scasw": "scasd"; + } + break; + case 0xb0: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0xb1: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "cl, %x", (void *)*b); + break; + case 0xb2: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "dl, %x", (void *)*b); + break; + case 0xb3: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0xb4: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "ah, %x", (void *)*b); + break; + case 0xb5: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "ch, %x", (void *)*b); + break; + case 0xb6: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "dh, %x", (void *)*b); + break; + case 0xb7: + s = "mov"; + ++b; + snprintf(op1, sizeof(op1), "bh, %x", (void *)*b); + break; + case 0xb8: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "ax, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "eax, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xb9: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "cx, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "ecx, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xba: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "dx, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "edx, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xbb: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "bx, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "ebx, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xbc: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "sp, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "esp, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xbd: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "bp, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "ebp, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xbe: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "si, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "esi, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xbf: + s = "mov"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "di, %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1, sizeof(op1), "edi, %x", *(u32 *)++b); + b += 3; + } + break; + case 0xc0: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "rol"; + break; + case 1: + s = "ror"; + break; + case 2: + s = "rcl"; + break; + case 3: + s = "rcr"; + break; + case 4: + s = "shl"; + break; + case 5: + s = "shr"; + break; + case 6: + s = "shl"; + break; + case 7: + s = "sar"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0xc1: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "rol"; + break; + case 1: + s = "ror"; + break; + case 2: + s = "rcl"; + break; + case 3: + s = "rcr"; + break; + case 4: + s = "shl"; + break; + case 5: + s = "shr"; + break; + case 6: + s = "shl"; + break; + case 7: + s = "sar"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0xc2: + s = "retn"; + snprintf(op1, sizeof(op1), "%x", *(u16 *)++b); + ++b; + break; + case 0xc3: + s = "retn"; + break; + case 0xc4: + s = "les"; + b += decodeModSM_memonly(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0xc5: + s = "lds"; + b += decodeModSM_memonly(++b, op1, 0, flip_imm_sz ? 2: 3, flip_addr_sz); + break; + case 0xc6: + s = "mov"; + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u8 *)++b); + break; + case 0xc7: + s = "mov"; + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + len = strlen(op1); + if(flip_imm_sz){ + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1+len, sizeof(op1)-len, ", %x", *(u32 *)++b); + b += 3; + } + break; + case 0xc8: + s = "enter"; + snprintf(op1, sizeof(op1), "%x, %x", *(u16 *)(b+1), *(u8 *)(b+3)); + b += 3; + break; + case 0xc9: + s = "leave"; + break; + case 0xca: + s = "retf"; + snprintf(op1, sizeof(op1), "%x", *(u16 *)++b); + ++b; + break; + case 0xcb: + s = "retf"; + break; + case 0xcc: + s = "int 3"; + break; + case 0xcd: + s = "int"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)*b); + break; + case 0xce: + s = "into"; + break; + case 0xcf: + s = "iret"; + break; + case 0xd0: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "rol"; + break; + case 1: + s = "ror"; + break; + case 2: + s = "rcl"; + break; + case 3: + s = "rcr"; + break; + case 4: + s = "shl"; + break; + case 5: + s = "shr"; + break; + case 6: + s = "shl"; + break; + case 7: + s = "sar"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", 1"); + break; + case 0xd1: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "rol"; + break; + case 1: + s = "ror"; + break; + case 2: + s = "rcl"; + break; + case 3: + s = "rcr"; + break; + case 4: + s = "shl"; + break; + case 5: + s = "shr"; + break; + case 6: + s = "shl"; + break; + case 7: + s = "sar"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", 1"); + break; + case 0xd2: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "rol"; + break; + case 1: + s = "ror"; + break; + case 2: + s = "rcl"; + break; + case 3: + s = "rcr"; + break; + case 4: + s = "shl"; + break; + case 5: + s = "shr"; + break; + case 6: + s = "shl"; + break; + case 7: + s = "sar"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", cl"); + break; + case 0xd3: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "rol"; + break; + case 1: + s = "ror"; + break; + case 2: + s = "rcl"; + break; + case 3: + s = "rcr"; + break; + case 4: + s = "shl"; + break; + case 5: + s = "shr"; + break; + case 6: + s = "shl"; + break; + case 7: + s = "sar"; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, ", cl"); + break; + case 0xd4: + s = "aam"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)*b); + break; + case 0xd5: + s = "aad"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)*b); + break; + case 0xd6: + s = "salc"; + break; + case 0xd7: + s = "xlat"; + break; + case 0xd8: + if(*++b == 0xd1){ + s = "fcom st(1)"; + } else if(*b == 0xd9){ + s = "fcomp st(1)"; + } else{ + switch((*b&0x38)>>3){ + case 0: + s = "fadd"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 1: + s = "fmul"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 2: + s = "fcom"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 3: + s = "fcomp"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 4: + s = "fsub"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 5: + s = "fsubr"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 6: + s = "fdiv"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + case 7: + s = "fdivr"; + b += decodeModSM_float(b, op1, 1, 0, flip_addr_sz); + break; + default: + print("Invalid Mod R/M byte."); + return; + } + } + break; + case 0xe0: + s = "loopnz"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0xe1: + s = "loopz"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0xe2: + s = "loop"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0xe3: + s = "jcxz"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0xe4: + s = "in"; + ++b; + snprintf(op1, sizeof(op1), "al, %x", (void *)*b); + break; + case 0xe5: + s = "in"; + ++b; + snprintf(op1, sizeof(op1), flip_imm_sz ? "ax, %x": "eax, %x", (void *)*b); + break; + case 0xe6: + s = "out"; + ++b; + snprintf(op1, sizeof(op1), "%x, al", (void *)*b); + break; + case 0xe7: + s = "in"; + ++b; + snprintf(op1, sizeof(op1), flip_imm_sz ? "%x, ax": "%x, eax", (void *)*b); + break; + case 0xe8: + s = "call"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "%x", entry+(u32)b-(u32)f_entry+*(u16 *)++b+3); + b += 2; + } else{ + snprintf(op1, sizeof(op1), "%x",(void *)entry+(u32)b-(u32)f_entry+*(u32 *)++b+4); + b += 3; + } + break; + case 0xe9: + s = "jmp"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "near ptr %x", entry+(u32)b-(u32)f_entry+*(u16 *)++b+3); + ++b; + } else{ + snprintf(op1, sizeof(op1), "near ptr %x", (void *)entry+(u32)b-(u32)f_entry+*(u32 *)++b+4); + b += 3; + } + break; + case 0xea: + s = "jmp"; + if(flip_imm_sz){ + snprintf(op1, sizeof(op1), "%x:%x", *(u16 *)(b+2), *(u16 *)++b); + b += 3; + } else{ + snprintf(op1, sizeof(op1), "%x:%x", *(u16 *)(b+4), *(u32 *)++b); + b += 5; + } + break; + case 0xeb: + s = "jmp"; + ++b; + snprintf(op1, sizeof(op1), "%x", (void *)entry+(u32)b-(u32)f_entry+*b+1); + break; + case 0xec: + s = "in al, dx"; + break; + case 0xed: + s = flip_imm_sz ? "in ax, dx": "in eax, dx"; + break; + case 0xee: + s= "out dx, al"; + break; + case 0xef: + s = flip_imm_sz ? "out dx, ax": "out dx, eax"; + break; + case 0xf1: + s = "int 1"; + break; + case 0xf4: + s = "hlt"; + break; + case 0xf5: + s = "cmc"; + break; + case 0xf6: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "test"; + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, "%x", *(u8 *)++b); + break; + case 1: + s = "test"; + len = strlen(op1); + snprintf(op1+len, sizeof(op1)-len, "%x", *(u8 *)++b); + break; + case 2: + s = "not"; + break; + case 3: + s = "neg"; + break; + case 4: + s = "mul ax, al, "; + break; + case 5: + s = "imul ax, al, "; + break; + case 6: + s = "div al, ah, ax, "; + break; + case 7: + s = "idiv al, ah, ax, "; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + break; + case 0xf7: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + switch((*b&0x38)/8){ + case 0: + s = "test"; + len = strlen(op1); + if(flip_imm_sz){ + snprintf(op1+len, sizeof(op1)-len, "%x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1+len, sizeof(op1)-len, "%x", *(u32 *)++b); + b += 3; + } + break; + case 1: + s = "test"; + len = strlen(op1); + if(flip_imm_sz){ + snprintf(op1+len, sizeof(op1)-len, "%x", *(u16 *)++b); + ++b; + } else{ + snprintf(op1+len, sizeof(op1)-len, "%x", *(u32 *)++b); + b += 3; + } + break; + case 2: + s = "not"; + break; + case 3: + s = "neg"; + break; + case 4: + s = "mul rdx, rax, "; + break; + case 5: + s = "imul rdx, rax, "; + break; + case 6: + s = "div rdx, rax, "; + break; + case 7: + s = "idiv rdx, rax, "; + break; + default: + print("Invalid Mod R/M byte."); + return; + } + break; + case 0xf8: + s = "clc"; + break; + case 0xf9: + s = "stc"; + break; + case 0xfa: + s = "cli"; + break; + case 0xfb: + s = "sti"; + break; + case 0xfc: + s = "cld"; + break; + case 0xfd: + s = "std"; + break; + case 0xfe: + b += decodeModSM(++b, op1, 1, 0, flip_addr_sz); + if(!((*b&0x38)/8)){ + s = "inc"; + } else if((*b&0x38)/8 == 1){ + s = "dec"; + } else{ + print("Invalid Mod R/M byte."); + return; + } + break; + case 0xff: + switch((*++b&0x38)>>3){ + case 0: + s = "inc"; + b += decodeModSM(b, op1, 1, 0, flip_addr_sz); + break; + case 1: + s = "dec"; + b += decodeModSM(b, op1, 1, 0, flip_addr_sz); + break; + case 2: + s = "call"; + b += decodeModSM(b, op1, 1, 0, flip_addr_sz); + break; + case 3: + s = "callf"; + b += decodeModSM_memonly(b, op1, 1, 0, flip_addr_sz); + break; + case 4: + s = "jmp"; + b += decodeModSM(b, op1, 1, 0, flip_addr_sz); + break; + case 5: + s = "jmpf"; + b += decodeModSM_memonly(b, op1, 1, 0, flip_addr_sz); + break; + case 6: + s = "push"; + b += decodeModSM(b, op1, 1, 0, flip_addr_sz); + break; + default: + print("Invalid Mod R/M byte."); + return; + } + break; + default: + print("invalid opcode\r\n"); + return; + } + strcompressdelimiter(s,' '); + printf(" %X: %s %s\r\n", entry+(u32)a-(u32)f_entry, s, op1); + ++b; + + } + + return b-a; +} diff --git a/lib/shell.c b/lib/shell.c index 77cb726..56b7748 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -12,6 +12,7 @@ #include "shell.h" #include "multiboot2.h" #include "math.h" +#include "debug.h" static command commands[] = { {"reboot" , "", &rebootnow}, @@ -26,6 +27,7 @@ static command commands[] = { {"err" , "", &err}, {"test" , "", &test}, {"view" , "", &view}, + {"disasm" , "", &disasm} }; /*******************************************************************************/ @@ -64,6 +66,30 @@ int test(void) print("Fonction de test !\r\n"); } +/*******************************************************************************/ +/* Desassemble une zone de mémoire donnée */ + +int disasm(u8* commandline) +{ + u8 arg[] = " \000"; + u8* size; + u8* pointer; + + if (strgetnbitems(commandline, ' ') < 3) + { + print("Syntaxe de la commande DISASM\r\ndisasm \33[32madresse taille\r\n\r\n \33[32madresse\33[0m\33[0m\33[25D\33[10C - Adresse a visualiser\r\n \33[32mtaille\33[0m\33[25D\33[10C - nombre d'octets a desassembler <256\r\n"); + return; + } + strgetitem(commandline, &arg, ' ', 1); + size=pointer=strtoint(&arg); + strgetitem(commandline, &arg, ' ', 2); + size+=strtoint(&arg); + while(pointer0x80 = graphique)\r\n"); + print("Syntaxe de la commande MODE\r\nmode \33[32mmodevideo\r\n\r\n modevideo\33[0m\33[25D\33[10C - mode video a initialiser (>0x80 = graphique)\r\n"); return; } strgetitem(commandline, &arg, ' ', 1); diff --git a/lib/vga.c b/lib/vga.c index 602882b..9d03176 100755 --- a/lib/vga.c +++ b/lib/vga.c @@ -306,13 +306,9 @@ void scroll_unchain(u8 lines, u8 attrib) void scroll_chain(u8 lines, u8 attrib) { if (scrolling) { - memcpy((u8 *) basemem + activepage * pagesize + - linesize * 8 * lines, - (u8 *) basemem + activepage * pagesize, - pagesize - linesize * 8 * lines, 1); - memset((u8 *) (basemem + activepage * pagesize + pagesize - - linesize * 8 * lines), attrib & 0x0F, - linesize * 8 * lines, 1); + memcpy((u8 *) basemem + activepage * pagesize + linesize * 8 * lines, + (u8 *) basemem + activepage * pagesize, pagesize - linesize * 8 * lines, 1); + memset((u8 *) (basemem + activepage * pagesize + pagesize - linesize * 8 * lines), attrib & 0x0F, linesize * 8 * lines, 1); } } diff --git a/lib/video.c b/lib/video.c index 37f073b..eec5c75 100755 --- a/lib/video.c +++ b/lib/video.c @@ -326,6 +326,8 @@ u32 storestr(u8* src, u8** dest, u32 len) { return len; } +#define maxbuffersize 1024 + /*******************************************************************************/ /* affiche une chaine de caractère formaté a l'ecran */ @@ -333,7 +335,7 @@ u32 printf(const u8 * string, ...) { va_list args; va_start(args, string); - format(string, args, &printstr, NULL); + vprintf(string, args); va_end(args); } @@ -344,18 +346,49 @@ u32 sprintf(u8 *variable, const u8 *string, ...) { va_list args; va_start(args, string); - - format(string, args, &storestr, variable); + vsprintf(variable, string, args); va_end(args); } +/*******************************************************************************/ +/* met une chaine de caractère formaté dans une variable de taille fixée */ + +u32 snprintf(u8 *variable, u32 maxsize, const u8 *string, ...) +{ + va_list args; + va_start(args, string); + vsnprintf(variable, maxsize, string, args); + va_end(args); +} + +/*******************************************************************************/ +/* affiche une chaine de caractère formaté a l'ecran depuis vararg */ + +u32 vprintf(const u8 * string, va_list args) +{ + format(string, args, maxbuffersize, &printstr, NULL); +} + +/*******************************************************************************/ +/* met une chaine de caractère formaté dans une variable depuis vararg */ + +u32 vsprintf(u8 *variable, const u8 *string, va_list args) +{ + format(string, args, maxbuffersize, &storestr, variable); +} + +/*******************************************************************************/ +/* met une chaine de caractère formaté dans une variable de taille fixée depuis vararg */ + +u32 vsnprintf(u8 *variable, u32 maxsize, const u8 *string, va_list args) +{ + format(string, args, maxsize, &storestr, variable); +} /*******************************************************************************/ /* affiche une chaine de caractère formaté a l'ecran */ -#define maxsize 1024 - -u32 format(const u8 * string, va_list args, u32 (*fonction)(u8* src, u8** dest, u32 len), u8* dest) +u32 format(const u8 * string, va_list args, u32 maxsize, u32 (*fonction)(u8* src, u8** dest, u32 len), u8* dest) { u64 sizes[] = { 0xFF, 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFF }; u8 units[][4] = { "o\000\000", "kio", "mio", "gio", "tio", "pio" }; @@ -365,7 +398,7 @@ u32 format(const u8 * string, va_list args, u32 (*fonction)(u8* src, u8** dest, u8 hexadecimal[] = "*0x\000"; u8 achar, temp; u8 asize, charadd, unit, precisioni, precisionf; - u8 buffer[maxsize]; + u8 buffer[maxbuffersize]; u8* bufferend; u32 buffersize; u8 *str = string;