otccelfn.c编译出来的ELF,格式太古老运行不了。80386 Programmer's Reference Manual
试了点高档些的办法,太麻烦了,还是做个虚拟机吧:
#include <stdio.h> #include <stdlib.h> typedef unsigned char byte; byte mem[65536]; int reg[32]; #define eax reg[0] #define ecx reg[2] #define eip reg[15] #define esp reg[14] #define ebp reg[13] #define _(i) break; inline int rmem(byte* p) { return *p | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); } // little endian inline int rmem(int a) { return rmem(mem + a); } // little endian inline void wmem(int a, int v) { *((int*)&mem[a]) = v; } // 4 bytes void print() { printf("%3x: %02x sp %04x bp %04x ax %04x cx %04x | ", eip, mem[eip], esp, ebp, eax, ecx); for (int j = 0; j < 16; j++) printf("%02x ", mem[esp+j]); getchar(); } int main() { FILE* fp = fopen("a.bin", "rb"); fread(mem, 1, sizeof(mem), fp); fclose(fp); for (esp = 65532;;) { byte op = mem[eip], *p = &mem[eip]; print(); int i; switch (op) { case 0x0f: eax *= ecx; eip += 3; _(imul %ecx %eax) case 0x50: wmem(esp -= 4, eax); ++eip; _(push %eax) case 0x55: wmem(esp -= 4, ebp); ++eip; _(push %ebp) case 0x59: ecx = mem[esp]; esp += 4; ++eip; _(pop %ecx) case 0x81: if (p[1] == 0xec) { esp -= rmem(p+2); eip += 6; } else if (p[1] == 0xc4) { esp += rmem(p+2); eip += 6; } break; case 0x89: if (p[1] == 0xe5) { ebp = esp; eip += 2; } // mov %esp,%ebp else if (p[1] == 0x84) { wmem(esp + rmem(p+3), eax); eip += 7; } // mov %eax,imm(%esp) else if (p[1] == 0x85) { wmem(ebp + rmem(p+2), eax); eip += 6; } // mov %eax,imm(%ebp) break; case 0x8b: if (p[1] == 0x85) { eax = mem[ebp + rmem(p+2)]; eip += 6; } // mov imm(%ebp),%eax break; case 0xb8: eax = rmem(p+1); eip += 5; _(mov imm %eax) case 0xc3: { eip = rmem(esp); esp += 4; } _(pop) case 0xc9: { ebp = rmem(esp = ebp); esp += 4; ++eip;} _(leave) case 0xcd: exit(0); case 0xe8: eip += 5; i = rmem(p+1); if (i == -4) { printf("printf: %d\n", rmem(esp + 4)); } else { wmem(esp -= 4, eip); eip += i; } break; }} return 0; }
C:
fn(i) { i = i * 3; printf("%d\n", i); } main() { fn(3); }
汇编:
0: e8 4d 00 00 00 call 0x52 5: cd 80 int $0x80 7: 55 push %ebp 8: 89 e5 mov %esp,%ebp a: 81 ec 00 00 00 00 sub $0x0,%esp 10: 8b 85 08 00 00 00 mov 0x8(%ebp),%eax 16: 50 push %eax 17: b8 03 00 00 00 mov $0x3,%eax 1c: 59 pop %ecx 1d: 0f af c1 imul %ecx,%eax 20: 89 85 08 00 00 00 mov %eax,0x8(%ebp) 26: 81 ec 08 00 00 00 sub $0x8,%esp 2c: b8 fc 68 00 00 mov $0x68fc,%eax 31: 89 84 24 00 00 00 00 mov %eax,0x0(%esp) 38: 8b 85 08 00 00 00 mov 0x8(%ebp),%eax 3e: 89 84 24 04 00 00 00 mov %eax,0x4(%esp) 45: e8 fc ff ff ff call 0x46 4a: 81 c4 08 00 00 00 add $0x8,%esp 50: c9 leave 51: c3 ret 52: 55 push %ebp 53: 89 e5 mov %esp,%ebp 55: 81 ec 00 00 00 00 sub $0x0,%esp 5b: 81 ec 04 00 00 00 sub $0x4,%esp 61: b8 03 00 00 00 mov $0x3,%eax 66: 89 84 24 00 00 00 00 mov %eax,0x0(%esp) 6d: e8 95 ff ff ff call 0x7 72: 81 c4 04 00 00 00 add $0x4,%esp 78: c9 leave 79: c3 ret
改进中:
gcd(a, b) { int i; i = a - b; if (i == 0) return a; else if (i > 0) return gcd(i, b); else return gcd(a, -i); } tonum(s) { int n, i; for (n = 0; ;s++) { if ((i = *(char*)s) == 0) break; n = n * 10 + i - '0'; } return n; } main() { int i, j; i = tonum("20"); j = tonum("24"); printf("%d\n", gcd(i, j)); return 0; }标签:00,return,esp,虚拟机,mov,玩具,eax,ebp From: https://www.cnblogs.com/funwithwords/p/17015853.html