int32_t instr_movsb(struct emu_cpu *c, struct emu_cpu_instruction *i) { if (i->prefixes & PREFIX_OPSIZE ) { UNIMPLEMENTED(c, SST); } if (i->prefixes & PREFIX_F3 || i->prefixes & PREFIX_F2) { /* Copy ECX bytes from DS:[ESI] to ES:[EDI] */ if (c->reg[ecx] > 0 ) { uint8_t tmp; c->reg[ecx]--; c->repeat_current_instr = true; MEM_BYTE_READ(c, c->reg[esi], &tmp); MEM_BYTE_WRITE(c, c->reg[edi], tmp); if ( !CPU_FLAG_ISSET(c,f_df) ) { /* increment */ c->reg[edi] += 1; c->reg[esi] += 1; } else { /* decrement */ c->reg[edi] -= 1; c->reg[esi] -= 1; } } else{ c->repeat_current_instr = false; } } else { /* a4 move ds:esi -> es->edi */ uint8_t tmp; MEM_BYTE_READ(c, c->reg[esi], &tmp); MEM_BYTE_WRITE(c, c->reg[edi], tmp); if ( !CPU_FLAG_ISSET(c,f_df) ) { /* increment */ c->reg[edi] += 1; c->reg[esi] += 1; } else { /* decrement */ c->reg[edi] -= 1; c->reg[esi] -= 1; } } return 0; }
//dzzie 5.19.11 - http://pdos.csail.mit.edu/6.828/2004/readings/i386/MOVS.htm int32_t instr_movs_a5(struct emu_cpu *c, struct emu_cpu_instruction *i) { if (i->prefixes & PREFIX_ADSIZE ) { UNIMPLEMENTED(c, SST); return 0; } uint8_t incSize = 0; if ( i->prefixes & PREFIX_OPSIZE ) //16bit { uint16_t tmp; MEM_WORD_READ(c, c->reg[esi], &tmp); MEM_WORD_WRITE(c, c->reg[edi], tmp); incSize = 2; } else{ //32bit uint32_t tmp2; MEM_DWORD_READ(c, c->reg[esi], &tmp2); MEM_DWORD_WRITE(c, c->reg[edi], tmp2); incSize = 4; } if (i->prefixes & PREFIX_F3) /* rep prefix - Copy ECX bytes from DS:[ESI] to ES:[EDI] */ { c->repeat_current_instr = false; if (c->reg[ecx] > 0 ){ c->reg[ecx]--; c->repeat_current_instr = true; }else{ return 0; //rep operation complete..do not adjust registers any more } } if ( !CPU_FLAG_ISSET(c,f_df) ){ /* increment */ c->reg[edi] += incSize; c->reg[esi] += incSize; } else{ /* decrement */ c->reg[edi] -= incSize; c->reg[esi] -= incSize; } return 0; }
void emu_cpu_debug_print(struct emu_cpu *c) { logDebug(c->emu,"cpu state eip=0x%08x\n", c->eip); logDebug(c->emu,"eax=0x%08x ecx=0x%08x edx=0x%08x ebx=0x%08x\n", c->reg[eax], c->reg[ecx], c->reg[edx], c->reg[ebx]); logDebug(c->emu,"esp=0x%08x ebp=0x%08x esi=0x%08x edi=0x%08x\n", c->reg[esp], c->reg[ebp], c->reg[esi], c->reg[edi]); char *fmsg; fmsg = (char *)malloc(32*3+1); memset(fmsg, 0, 32*3+1); int i; for ( i=0;i<32;i++ ) { if ( CPU_FLAG_ISSET(c, i) ) { strcat(fmsg, eflagm[i]); strcat(fmsg," "); } } logDebug(c->emu,"Flags: %s\n", fmsg); free(fmsg); return; for (i=0; i<8; i++) { printf("%08x ",c->reg[esp] + i * 4); } printf("\n"); for (i=0; i<8; i++) { uint32_t d; emu_memory_read_dword(c->mem, c->reg[esp] + i * 4, &d); printf("%08x ",d); } printf("\n"); }
int32_t instr_aaa_37(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* 37 * ASCII adjust AL after add * AAA */ if ( ((*c->reg8[al] & 0x0f) > 9) || CPU_FLAG_ISSET(c,f_af)) { *c->reg8[al] = *c->reg8[al] + 6; *c->reg8[ah] = *c->reg8[ah] + 1; CPU_FLAG_SET(c,f_af); CPU_FLAG_SET(c,f_cf); }else { CPU_FLAG_UNSET(c,f_af); CPU_FLAG_UNSET(c,f_cf); } *c->reg8[al] = (*c->reg8[al] & 0x0f); return 0; }
int32_t instr_lods_ac(struct emu_cpu *c, struct emu_cpu_instruction *i) { /* AC * Load byte at address DS:(E)SI into AL * LODS m8 */ /* AC * Load byte at address DS:(E)SI into AL * LODSB */ if ( i->prefixes & PREFIX_ADSIZE ) { // MEM_BYTE_READ(c, c->reg16[si], c->reg8[al]); UNIMPLEMENTED(c, SST); } else { MEM_BYTE_READ(c, c->reg[esi], c->reg8[al]); if ( CPU_FLAG_ISSET(c,f_df) ) { /* decrement */ c->reg[esi] -= 1; } else { /* increment */ c->reg[esi] += 1; } //TRACK_INIT_REG8(c->instr, al); } return 0; }
int32_t instr_lods_ad(struct emu_cpu *c, struct emu_cpu_instruction *i) { if ( i->prefixes & PREFIX_OPSIZE ) { /* AD * Load word at address DS:(E)SI into AX * LODS m16 */ /* AD * Load word at address DS:(E)SI into AX * LODSW */ if ( i->prefixes & PREFIX_ADSIZE ) { // MEM_WORD_READ(c, c->reg16[si], c->reg16[ax]); UNIMPLEMENTED(c, SST); } else { MEM_WORD_READ(c, c->reg[esi], c->reg16[ax]); if (CPU_FLAG_ISSET(c,f_df)) { /* decrement */ c->reg[esi] -= 2; }else { /* increment */ c->reg[esi] += 2; } } } else { /* AD * Load doubleword at address DS:(E)SI into EAX * LODS m32 */ /* AD * Load doubleword at address DS:(E)SI into EAX * LODSD */ if ( i->prefixes & PREFIX_ADSIZE ) { // MEM_DWORD_READ(c, c->reg16[si], &c->reg[eax]); UNIMPLEMENTED(c, SST); } else { MEM_DWORD_READ(c, c->reg[esi], &c->reg[eax]); if (CPU_FLAG_ISSET(c,f_df)) { /* decrement */ c->reg[esi] -= 4; }else { /* increment */ c->reg[esi] += 4; } //TRACK_INIT_REG32(c->instr, eax); } } return 0; }