Skip to content

Instantly share code, notes, and snippets.

@satokjp
Last active December 20, 2015 14:49
Show Gist options
  • Save satokjp/6149879 to your computer and use it in GitHub Desktop.
Save satokjp/6149879 to your computer and use it in GitHub Desktop.
x86 a.out binary C mac
/*
Compile : cc runrun.c -o runrun
Execute : ./runrun a.out -> run mode
./runrun -d a.out -> disassemble mode (not run)
*/
/*
usage: 7run [-p] [-d|-v/-s] cmd [args ...]
-p: PDP-11 mode
-8: 8086/V6 mode
-d: disassemble mode (not run)
-m: verbose mode with memory dump
-v: verbose mode (output syscall and disassemble)
-s: syscall mode (output syscall)
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
uint8_t mem[0x10000];
int tsize; // .text area size
int dsize; // .data area size
/**************************************************/
// read 8 bits
/**************************************************/
//uint16_t read8(int i){
uint8_t read8(int i){
return mem[i] ;
}
/**************************************************/
// read 16 bits
/**************************************************/
uint16_t read16(int i){
return mem[i] | (mem[i + 1] << 8);
}
/**************************************************/
// Big Endian
/**************************************************/
uint16_t w_s_uint16(int i){
return ( mem[i] << 8 ) | mem[i + 1] ;
}
/**************************************************/
// write 8 bits
/**************************************************/
//uint8_t write8(int i,uint8_t b){
uint8_t write8(uint16_t i,uint8_t b){
mem[i] = b;
return 0 ;
}
/**************************************************/
// write 8 bits al
/**************************************************/
uint8_t write8l(uint16_t i,uint16_t w){
mem[i] = w;
return 0 ;
}
/**************************************************/
// write 8 bits ah
/**************************************************/
uint8_t write8h(uint16_t i,uint16_t w){
mem[i] = w >> 8;
return 0 ;
}
/**************************************************/
// write 16 bits
/**************************************************/
uint16_t write16(uint16_t i,uint16_t w){
//printf("write16 : %d (0x%02x) 0x%02x \n",i,i,w);
mem[i] = w ;
mem[i+1] = ( w >> 8 ) ;
return 0 ;
}
/**************************************************/
// write 16 bits
/**************************************************/
uint16_t write16a(uint16_t i, uint16_t w0, uint16_t w1){
// w0: offset
//printf("write16a: %d (0x%02x) 0x%02x 0x%02x \n",i,i,w0,w1);
mem[i+w0] = w1 ;
mem[i+w0+1] = ( w1 >> 8 ) ;
return 0 ;
}
/**************************************************/
/**************************************************/
int runrun()
{
// ax:registar
uint16_t ax = 0;
// bx:registar
uint16_t bx = 0;
// cx:registar
uint16_t cx = 0;
// dx:registar
uint16_t dx = 0;
// sp:registar
uint16_t sp = 0;
// bp:registar
uint16_t bp = 0;
// si:registar
uint16_t si = 0;
// di:registar
uint16_t di = 0;
// interlapt no
int intn = 0;
// syswrite
int w_start,w_no;
uint8_t b0,b1;
uint16_t w0,w1;
for (int pc = 0; pc < tsize; pc++) {
b0 = read8(pc);
switch (b0){
case 0x80 :
// mov [bx]
b0 = read8(pc+1);
switch (b0){
case 0x2e :
// sub byte [], al
//printf("0x802e\n");
mem[read16(pc+2)] = mem[read16(pc+2)] - read8(pc+4);
pc += 4 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0x81 :
// mov [bx]
b0 = read8(pc+1);
switch (b0){
case 0x2e :
// sub [], al
//printf("0x812e %04x %02x\n",read16(pc+2),read8(pc+4) );
mem[read16(pc+2)] = mem[read16(pc+2)] - read8(pc+4);
mem[read16(pc+2)+1] = mem[read16(pc+2)+1] - read8(pc+5);
pc += 5 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0x88 :
// mov [bx]
b0 = read8(pc+1);
switch (b0){
case 0x07 :
// mov [bx], al
//printf("0x8807\n");
write8l(bx,ax);
pc += 1 ;
break;
case 0x67 :
// mov [bx+2],ah
b0 = read8(pc+2);
//printf("0x8867%02x\n",b0);
write8h(bx + b0,ax);
pc += 2 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0x89 :
// mov [bx]
b0 = read8(pc+1);
switch (b0){
case 0x07 :
// mov [bx], ax
//printf("0x8907\n");
write16(bx,ax);
pc += 1 ;
break;
case 0x0f :
// mov [bx], cx
//printf("0x890f\n");
write16(bx,cx);
pc += 1 ;
break;
case 0x4f :
// mov [bx+2],cx
//printf("089x4f\n");
b0 = read8(pc+2);
write16a(bx,b0,cx);
pc += 2 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0x8b :
// mov [bx]
b0 = read8(pc+1);
switch (b0){
case 0x0e :
// mov cx
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
case 0x16 :
// mov dx
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
case 0x1e :
// mov bx
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
case 0x26 :
// mov sp
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
case 0x2e :
// mov bp
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
case 0x36 :
// mov si
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
case 0x3e :
// mov di
w0 = read16(pc+2);
printf("0x8b%02x%04x\n",b0,w0);
//write16(bx,ax);
pc += 3 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0xa1 :
// mov ax,
w0 = read16(pc+1) ;
//cx = (cx & 0xff00) | b0;
printf("0xa1%04x\n",w0);
pc += 2 ;
break;
case 0xb1 :
// mov cl,
b0 = read8(pc+1) ;
cx = (cx & 0xff00) | b0;
//printf("0xb1%02x\n",b0);
pc += 1 ;
break;
case 0xb5 :
// mov ch,
b0 = read8(pc+1) ;
cx = (cx & 0x00ff) | b0 << 8;
//printf("0xb5%02x\n",b0);
pc += 1 ;
break;
case 0xb8 :
// mov ax,
w0 = read16(pc+1);
ax = w0 ;
pc += 2 ;
//printf("mov ax,%02x\n",ax);
break;
case 0xb9 :
// mov cx,
w0 = read16(pc+1);
cx = w0 ;
pc += 2 ;
//printf("0xb9\n");
break;
case 0xbb :
// mov bx,
w0 = read16(pc+1);
bx = w0 ;
pc += 2 ;
//printf("mov bx,%d\n",bx);
break;
case 0xc6 :
// mov byte [bx] / movb
b0 = read8(pc+1);
switch (b0){
case 0x06 :
//printf("0xc606\n");
w0 = read16(pc+2);
b0 = read8(pc+4);
mem[w0] = b0;
//write8(bx, read8(pc+2));
pc += 4 ;
break;
case 0x07 :
//printf("0x07\n");
write8(bx, read8(pc+2));
pc += 2 ;
break;
case 0x47 :
//printf("0x47\n");
b0 = read8(pc+2);
//printf("w0=%d\n",w0);
write8(bx+b0, read8(pc+3));
pc += 3 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0xc7 :
// mov [bx],
b0 = read8(pc+1);
switch (b0){
case 0x06 :
//printf("0xc706\n");
w0 = read16(pc+2);
w1 = read16(pc+4);
write16(w0,w1);
//write8(bx, read8(pc+2));
//write8(bx+1,read8(pc+3));
pc += 5 ;
break;
case 0x07 :
//printf("0x07\n");
write8(bx, read8(pc+2));
write8(bx+1,read8(pc+3));
pc += 3 ;
break;
case 0x47 :
//printf("0x47\n");
w0 = read8(pc+2);
//printf("w0=%d\n",w0);
write8(bx+w0, read8(pc+3));
write8(bx+w0+1,read8(pc+4));
pc += 4 ;
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
break;
case 0xcd :
// int
b0 = read8(pc+1);
intn = b0;
//printf("int %d\n",intn);
b0 = read8(pc+2);
if ( b0 == 0x04 ) {
// int 0x04
//printf(";syswrite\n");
w0 = read16(pc+3);
w_start = w0;
w0 = read16(pc+5);
w_no = w0;
//printf("%d %d\n",w_start,w_no);
pc += 6;
#if 1
// system call
write(ax,mem+w_start,w_no);
#else
for(int j=w_start; j < w_start+w_no ; j++){
putchar(mem[j]);
}
#endif
} else if(b0 == 0x01 ) {
// int 0x01
#if 0
printf(";sys exit\n");
#else
printf("%d\n",ax);
#endif
pc += 3;
}
break;
default :
// error
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
break;
}
}
return 0;
}
/**************************************************/
// disassemble
/**************************************************/
int disassemble()
{
uint8_t b0;
uint16_t w0,w1;
// .text
printf("session: .text \n");
for (int pc = 0; pc < tsize; pc++) {
b0 = read8(pc) ;
//pc += 1;
//printf("%04x:",pc);
//printf("pc=%d %02x \n",pc,b0);
switch (b0){
case 0x80 :
// mov [bx]
b0 = read8(pc+1) ;
switch (b0){
case 0x2e :
// mov [bx], al
//printf("0x802e\n");
w0 = read16(pc+2) ;
b0 = read16(pc+4) ;
printf("%04x: %02x%02x%02x%02x%02x \t sub byte [%04x], %02x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),read8(pc+4),w0,b0);
pc += 4;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0x81 :
// mov [bx]
b0 = read8(pc+1) ;
switch (b0){
case 0x2e :
// mov [bx], al
//printf("0x812e\n");
w0 = read16(pc+2) ;
w1 = read16(pc+4) ;
printf("%04x: %02x%02x%02x%02x%02x%02x \t sub [%04x], %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),read8(pc+4),read8(pc+5),w0,w1);
pc += 5;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0x88 :
// mov [bx]
b0 = read8(pc+1) ;
switch (b0){
case 0x07 :
// mov [bx], al
b0 = read16(pc+2) ;
printf("%04x: %02x%02x \t\t mov [bx], al \n",pc,read8(pc),read8(pc+1));
pc += 1;
break;
case 0x67 :
// mov [bx+2], ah
printf("%04x: %02x%02x%02x \t\t mov [bx+%d], ah \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2));
pc += 2;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0x89 :
// mov [bx]
b0 = read8(pc+1) ;
switch (b0){
case 0x07 :
// mov [bx], ax
b0 = read16(pc+2) ;
printf("%04x: %02x%02x \t\t mov [bx], ax \n",pc,read8(pc),read8(pc+1));
pc += 1;
break;
case 0x0f :
// mov [bx], cx
printf("%04x: %02x%02x%02x \t\t mov [bx], cx \n",pc,read8(pc),read8(pc+1),read8(pc+2));
pc += 1;
break;
case 0x4f :
// mov [bx+2], cx
printf("%04x: %02x%02x%02x \t\t mov [bx+%d], cx \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2));
pc += 2;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0x8b :
// mov [bx]
b0 = read8(pc+1) ;
switch (b0){
case 0x0e :
// mov cx,
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov cx, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
case 0x16 :
// mov dx,
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov dx, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
case 0x1e :
// mov bx
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov bx, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
case 0x26 :
// mov sp,
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov sp, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
case 0x2e :
// mov bp,
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov bp, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
case 0x36 :
// mov si
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov si, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
case 0x3e :
// mov di
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov di, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+2),w0 );
pc += 3;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0xa1 :
// mov ax
w0 = read16(pc+1) ;
printf("%04x: %02x%02x%02x \t\t mov ax, [%04x] \n",pc,read8(pc),read8(pc+1),read8(pc+2),w0);
pc += 2;
break;
case 0xb1 :
// mov cl
b0 = read16(pc+1) ;
printf("%04x: %02x%02x \t\t mov cl, %02x \n",pc,read8(pc),read8(pc+1),b0);
pc += 1;
break;
case 0xb5 :
// mov ch
b0 = read16(pc+1) ;
printf("%04x: %02x%02x \t\t mov ch, %02x \n",pc,read8(pc),read8(pc+1),b0);
pc += 1;
break;
case 0xb8 :
// mov ax
w0 = read16(pc+1) ;
printf("%04x: %02x%02x%02x \t\t mov ax, %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),w0);
pc += 2;
break;
case 0xb9 :
// mov cx,
w0 = read16(pc+1) ;
printf("%04x: %02x%02x%02x \t\t mov cx, %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),w0);
pc += 2;
break;
case 0xbb :
// mov bx
w0 = read16(pc+1) ;
printf("%04x: %02x%02x%02x \t\t mov bx, %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),w0);
pc += 2;
break;
case 0xc6 :
// movb bx
b0 = read8(pc+1);
switch (b0){
case 0x06 :
// mov byte
//printf("0xc606\n");
w0 = read16(pc+2) ;
b0 = read16(pc+4) ;
printf("%04x: %02x%02x%02x%02x%02x \t mov byte [%04x], %02x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),read8(pc+4),w0,b0);
pc += 4;
break;
case 0x07 :
// movb (bx)
b0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x \t\t mov byte [bx], %02x \n",pc,read8(pc),read8(pc+1),read8(pc+2),b0);
pc += 2;
break;
case 0x47 :
// movb 2(bx) / mov [bx+2]
b0 = read16(pc+3) ;
printf("%04x: %02x%02x%02x%02x\t\t mov byte [bx+%d], %02x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),read8(pc+2),b0);
pc += 3;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0xc7 :
// mov bx
b0 = read8(pc+1);
switch (b0){
case 0x06 :
// mov (bx)
//printf("0xc706\n");
w0 = read16(pc+2) ;
w1 = read16(pc+4) ;
printf("%04x: %02x%02x%02x%02x%02x%02x \t mov [%04x], %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),read8(pc+4),read8(pc+5),w0,w1);
pc += 5;
break;
case 0x07 :
// mov (bx)
w0 = read16(pc+2) ;
printf("%04x: %02x%02x%02x%02x \t\t mov [bx], %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),w0);
pc += 3;
break;
case 0x47 :
// mov 2(bx) / mov [bx+2]
w0 = read16(pc+3) ;
printf("%04x: %02x%02x%02x%02x%02x\t mov [bx+%d], %04x \n",pc,read8(pc),read8(pc+1),read8(pc+2),read8(pc+3),read8(pc+4),read8(pc+2),w0);
pc += 4;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%02x \t\t ; undefined %04x \n",b0,b0);
break;
}
break;
case 0xcd :
// int
b0 = read8(pc+1);
switch (b0){
case 0x07 :
// int 7
printf("%04x: %02x%02x \t\t int %x \n",pc,read8(pc),read8(pc+1),read8(pc+1));
pc += 2;
b0 = read8(pc);
switch (b0){
case 0x01 :
// sys exit 1
printf("%04x: %02x \t\t ; sys exit \n",pc,b0);
//pc += 1;
break;
case 0x04 :
// sys write 4
printf("%04x: %02x \t\t ; sys write \n",pc,b0);
w0 = read16(pc+1) ;
printf("%04x: %02x%02x \t\t ; arg, %04x \n",pc,read8(pc+1),read8(pc+2),w0);
w0 = read16(pc+3) ;
printf("%04x: %02x%02x \t\t ; arg, %04x \n",pc,read8(pc+3),read8(pc+4),w0);
pc += 4;
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%04x: %02x \t\t ; undefined %04x \n",pc,b0,b0);
break;
}
break;
default :
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%04x: %02x \t\t ; undefined %04x \n",pc,b0,b0);
break;
}
//printf("%04x: %02x%02x \t\t int %x \n",pc,read8(pc),read8(pc+1),read8(pc+1));
//pc += 1;
break;
case 0x10 :
printf("%04x: %02x%02x \t\t ; arg \n",pc,read8(pc),read8(pc+1));
pc += 1;
break;
case 0x06 :
printf("%04x: %02x%02x \t\t ; arg \n",pc,read8(pc),read8(pc+1));
pc += 1;
break;
case 0x00 :
printf("%04x: %02x \t\t (undefined) \n",pc,b0);
pc += 1;
break;
default:
printf("error %04x: 0x%02x%02x%02x \n",pc,read8(pc),read8(pc+1),read8(pc+2) );
//printf("%04x: %02x \t\t ; arg def %04x \n",pc,b0,b0);
break;
}
}
// .data
printf("session: .data\n");
for (int pc = tsize; pc < tsize + dsize; pc += 2) {
w0 = w_s_uint16(pc);
printf("%04x: %04x\n", pc, w0);
}
return 0 ;
}
/**************************************************/
/**************************************************/
int file_read(char *fname)
{
FILE *f;
uint8_t header[16];
uint16_t w ;
printf("FileName:%s\n",fname);
// file open
f = fopen(fname, "rb");
if (!f) {
printf("file not found! : %s\n",fname);
return 1;
}
// read header area
fread(header, sizeof(header), 1, f);
// text size
w = header[2] | (header[3] << 8);
tsize = w ;
// data size
w = header[4] | (header[5] << 8);
dsize = w ;
printf("tsize = 0x%04x, dsize = 0x%04x\n", tsize, dsize);
// read text & data area
fread(mem, tsize + dsize, 1, f);
fclose(f);
return 0;
}
/**************************************************/
/**************************************************/
int main(int argc, char *argv[]) {
FILE *f;
// command line
if (argc == 2) {
// run
printf("run start!\n");
file_read(argv[1]);
runrun();
} else if ( argc == 3) {
if(*argv[1] == '-'){
char opt = *(argv[1]+1);
if(opt == 'd'){
// disassemble
printf("disassemble start !\n") ;
file_read(argv[2]);
disassemble();
}else{
printf("option error\n") ;
return 1;
}
} else {
printf("option error\n") ;
return 1;
}
} else {
printf("Command Line Error !\n");
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment