core/x86/decode.c
/* reads the modrm byte and any following sib and offset bytes */
reads the modrm byte and any following sib and offset bytes
reads the modrm byte and any following sib and offset bytes
static byte *
read_modrm(byte *pc, decode_info_t *di)
{
    byte modrm = *pc;
    pc++;
    di->modrm = modrm;
    di->mod = (byte)((modrm >> 6) & 0x3); 
    di->reg = (byte)((modrm >> 3) & 0x7); 
    di->rm  = (byte)(modrm & 0x7);        
    if (!X64_MODE(di) && TEST(PREFIX_ADDR, di->prefixes)) {
        di->has_sib = false;
        if ((di->mod == 0 && di->rm == 6) || di->mod == 2) {
            di->has_disp = true;
            if (di->mod == 0 && di->rm == 6) {
                di->disp = (int) *((ushort *)pc); 
            } else {
                di->disp = (int) *((short *)pc); 
            }
            pc += 2;
        } else if (di->mod == 1) {
            di->has_disp = true;
            di->disp = (int) (char) *pc; 
            pc++;
        } else {
            di->has_disp = false;
        }
    } else {
        if (di->rm == 4 && di->mod != 3) {
            byte sib = *pc;
            pc++;
            di->has_sib = true;
            di->scale = (byte)((sib >> 6) & 0x3); 
            di->index = (byte)((sib >> 3) & 0x7); 
            di->base  = (byte)(sib & 0x7);        
        } else {
            di->has_sib = false;
        }
        if ((di->mod == 0 && di->rm == 5) ||
            (di->has_sib && di->mod == 0 && di->base == 5) ||
            di->mod == 2) {
            di->has_disp = true;
            di->disp = *((int *)pc);
            IF_X64(di->disp_abs = pc); 
            pc += 4;
        } else if (di->mod == 1) {
            di->has_disp = true;
            di->disp = (int) (char) *pc; 
            pc++;
        } else {
            di->has_disp = false;
        }
    }
    return pc;
}
static byte * read_modrm ( byte * pc , decode_info_t * di ) { byte modrm = * pc ; pc ++ ; di -> modrm = modrm ; di -> mod = ( byte ) ( ( modrm >> 6 ) & 0x3 ) ; di -> reg = ( byte ) ( ( modrm >> 3 ) & 0x7 ) ; di -> rm = ( byte ) ( modrm & 0x7 ) ; if ( ! X64_MODE ( di ) && TEST ( PREFIX_ADDR , di -> prefixes ) ) { di -> has_sib = false ; if ( ( di -> mod == 0 && di -> rm == 6 ) || di -> mod == 2 ) { di -> has_disp = true ; if ( di -> mod == 0 && di -> rm == 6 ) { di -> disp = ( int ) * ( ( ushort * ) pc ) ; } else { di -> disp = ( int ) * ( ( short * ) pc ) ; } pc += 2 ; } else if ( di -> mod == 1 ) { di -> has_disp = true ; di -> disp = ( int ) ( char ) * pc ; pc ++ ; } else { di -> has_disp = false ; } } else { if ( di -> rm == 4 && di -> mod != 3 ) { byte sib = * pc ; pc ++ ; di -> has_sib = true ; di -> scale = ( byte ) ( ( sib >> 6 ) & 0x3 ) ; di -> index = ( byte ) ( ( sib >> 3 ) & 0x7 ) ; di -> base = ( byte ) ( sib & 0x7 ) ; } else { di -> has_sib = false ; } if ( ( di -> mod == 0 && di -> rm == 5 ) || ( di -> has_sib && di -> mod == 0 && di -> base == 5 ) || di -> mod == 2 ) { di -> has_disp = true ; di -> disp = * ( ( int * ) pc ) ; IF_X64 ( di -> disp_abs = pc ) ; pc += 4 ; } else if ( di -> mod == 1 ) { di -> has_disp = true ; di -> disp = ( int ) ( char ) * pc ; pc ++ ; } else { di -> has_disp = false ; } } return pc ; }
reads the modrm byte and any following sib and offset bytes
reads the modrm byte and any following sib and offset bytes
/* top 2 bits */ /* middle 3 bits */ /* bottom 3 bits */ /* addr16 displacement */ /* 2-byte disp */ /* treat absolute addr as unsigned */ /* zero-extend */ /* treat relative addr as signed */ /* sign-extend */ /* 1-byte disp */ /* sign-extend */ /* 32-bit, which sometimes has a SIB */ /* need SIB */ /* top 2 bits */ /* middle 3 bits */ /* bottom 3 bits */ /* displacement */ /* 4-byte disp */ /* used to set instr->rip_rel_pos */ /* 1-byte disp */ /* sign-extend */