diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2008-07-27 19:38:15 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2008-07-27 19:38:15 (GMT) |
commit | 1bf9c5ebe8bb3326e10491974cd43b221e2a56a1 (patch) | |
tree | 01a745a798661478eb7a6e02c0a0831bb1b4950c /src/arch/x86/processor.c | |
parent | dbf4d1f93e54251568854bff0ebc9c84f60857f6 (diff) |
Supported new x86 opcodes (nop and mov).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@7 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/x86/processor.c')
-rw-r--r-- | src/arch/x86/processor.c | 105 |
1 files changed, 80 insertions, 25 deletions
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 4ef1377..895c8b1 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -24,30 +24,34 @@ #include "processor.h" +#include <malloc.h> +#include <stdio.h> + + #include "../processor-int.h" #include "instruction.h" #include "opcodes.h" - - -#include <malloc.h> +#include "operand.h" -typedef asm_x86_instr * (* read_instr) (const char *, off_t *, off_t); +typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t); /* Carte d'identité d'un opcode */ typedef struct _x86_opcode { - char opcode; /* Opcode + préfixe eventuel */ + uint8_t prefix; /* préfixe eventuel */ + uint8_t opcode; /* Opcode seul */ const char *name; /* Désignation humaine */ read_instr read; /* Décodage de l'instruction */ } x86_opcode; -#define register_opcode(target, bin, n, func) \ +#define register_opcode(target, pre, bin, n, func) \ do {\ +target.prefix = pre; \ target.opcode = bin; \ target.name = n; \ target.read = func; \ @@ -72,7 +76,7 @@ void x86_register_instructions(asm_x86_processor *); /* Décode une instruction dans un flux de données. */ -asm_instr *x86_fetch_instruction(const asm_x86_processor *, const char *, off_t *, off_t); +asm_instr *x86_fetch_instruction(const asm_x86_processor *, const uint8_t *, off_t *, off_t); /* Traduit une instruction en version humainement lisible. */ void x86_print_instruction(const asm_x86_processor *, const asm_x86_instr *, char *, size_t, AsmSyntax); @@ -129,11 +133,32 @@ void x86_register_instructions(asm_x86_processor *proc) - register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", read_instr_int); + register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop); + register_opcode(proc->opcodes[X86_OP_MOV_AX], 0x00, 0xb8, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xb9, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xba, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_BX], 0x00, 0xbb, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_SP], 0x00, 0xbc, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_BP], 0x00, 0xbd, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_SI], 0x00, 0xbe, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_DI], 0x00, 0xbf, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", read_instr_int); + + + + register_opcode(proc->opcodes[X86_OP_MOV_EAX], 0x66, 0xb8, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_ECX], 0x66, 0xb9, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EDX], 0x66, 0xba, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EBX], 0x66, 0xbb, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_ESP], 0x66, 0xbc, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EBP], 0x66, 0xbd, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_ESI], 0x66, 0xbe, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EDI], 0x66, 0xbf, "mov", read_instr_mov_to_1632); + } @@ -155,25 +180,17 @@ void x86_register_instructions(asm_x86_processor *proc) * * ******************************************************************************/ -asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const char *data, off_t *pos, off_t len) +asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len) { asm_x86_instr *result; /* Résultat à faire remonter */ X86Opcodes i; /* Boucle de parcours */ result = NULL; - //printf("--------\n"); - for (i = 0; i < X86_OP_COUNT; i++) { - - /* - printf(" cmp :: 0x%02hhx vs 0x%02hhx ? %d\n", - data[*pos], proc->opcodes[i].opcode, - data[*pos] == proc->opcodes[i].opcode); - */ - - if (data[*pos] == proc->opcodes[i].opcode) + if ((proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode) + || (proc->opcodes[i].prefix == 0 && data[*pos] == proc->opcodes[i].opcode)) { result = proc->opcodes[i].read(data, pos, len); if (result != NULL) result->type = i; @@ -182,7 +199,6 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const char *data } - return ASM_INSTRUCTION(result); } @@ -206,17 +222,56 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const char *data void x86_print_instruction(const asm_x86_processor *proc, const asm_x86_instr *instr, char *buffer, size_t len, AsmSyntax syntax) { + size_t i; /* Boucle de parcours */ + char opbuffer[3][64]; /* Tampon pour les textes */ - if (ASM_INSTRUCTION(instr)->opcode == DB_OPCODE) - + /* Impression des opérandes */ - snprintf(buffer, len, "db\t0x%02hhx", ASM_INSTRUCTION(instr)->operands[0].value.val8); + for (i = 0; i < ASM_INSTRUCTION(instr)->operands_count; i++) + switch (ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i])->type) + { + case AOT_NONE: + print_db_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 64, syntax); + break; + case AOT_IMM: + print_imm_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 64, syntax); + break; + case AOT_REG: + x86_print_reg_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 64, syntax); + break; + case AOT_MEM: + break; + } + /* Impression globale finale */ - else + if (ASM_INSTRUCTION(instr)->opcode == DB_OPCODE) + snprintf(buffer, len, "db\t%s", opbuffer[0]); - snprintf(buffer, len, "%s\t0x%02hhx", proc->opcodes[instr->type].name, ASM_INSTRUCTION(instr)->operands[0].value.val8); + else + switch (ASM_INSTRUCTION(instr)->operands_count) + { + case 0: + snprintf(buffer, len, "%s", proc->opcodes[instr->type].name); + break; + + case 1: + snprintf(buffer, len, "%s\t%s", proc->opcodes[instr->type].name, opbuffer[0]); + break; + + case 2: + switch (syntax) + { + case ASX_INTEL: + snprintf(buffer, len, "%s\t%s, %s", proc->opcodes[instr->type].name, opbuffer[0], opbuffer[1]); + break; + case ASX_ATT: + snprintf(buffer, len, "%s\t%s, %s", proc->opcodes[instr->type].name, opbuffer[1], opbuffer[0]); + break; + } + break; + } } |