📄 decode.c
字号:
case 6: case 7: DECODE_PRINTF("ILLEGAL SEGREG"); break; } HALT_SYS(); return NULL; /* NOT REACHED OR REACHED ON ERROR */}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=00 addressing. Also enables thedecoding of instructions.NOTE: The code which specifies the corresponding segment (ds vs ss) below in the case of [BP+..]. The assumption here is that at the point that this subroutine is called, the bit corresponding to SYSMODE_SEG_DS_SS will be zero. After every instruction except the segment override instructions, this bit (as well as any bits indicating segment overrides) will be clear. So if a SS access is needed, set this bit. Otherwise, DS access occurs (unless any of the segment override bits are set).****************************************************************************/unsigned decode_rm00_address( int rm){ unsigned offset;#ifdef ADD_PREFIX_ADDR{ u32 *rp; int ss,index,base; u32 basereg,indexreg,disp32; if (M.x86.mode & SYSMODE_PREFIX_ADDR) { M.x86.mode &=~ SYSMODE_PREFIX_ADDR; if(rm==4){//means a SIB follows the ModR/M byte FETCH_DECODE_SIB(ss, index, base);//fetch SIB byte if(base==5&&index==4) { printk("error in sib mode\n"); HALT_SYS(); } DECODE_PRINTF("["); if(base!=5){ rp=decode_rm_long_register(base); basereg=*rp; }else basereg=0; if(index!=4){//Scaled Index==5 means none index if(base!=5) DECODE_PRINTF("+"); rp=decode_rm_long_register(index); indexreg=*rp; if(ss!=0) DECODE_PRINTF2("*%x",1<<ss); indexreg*=(1<<ss); //mutilply scaled field }else indexreg=0; DECODE_PRINTF("]"); return( basereg+indexreg ); }else if(rm==5){ FETCH_DECODE_SIB(ss, index, base);//fetch SIB byte disp32=(s32)fetch_long_imm(); if(base==5||index==4){ DECODE_PRINTF2("[%x]",disp32); return disp32; }else DECODE_PRINTF2("%x",disp32); DECODE_PRINTF("["); if(base!=5){ rp=decode_rm_long_register(base); basereg=*rp; }else basereg=0; if(index!=4){//Scaled Index==5 means none index if(base!=5) DECODE_PRINTF("+"); rp=decode_rm_long_register(index); indexreg=*rp; if(ss!=0) DECODE_PRINTF2("*%x",1<<ss); indexreg*=(1<<ss); //mutilply scaled field }else indexreg=0; DECODE_PRINTF("]"); return( disp32+basereg+indexreg ); }else{ rp = decode_rm_long_register(rm); return (*rp); } }}#endif switch (rm) { case 0: DECODE_PRINTF("[BX+SI]"); return M.x86.R_BX + M.x86.R_SI; case 1: DECODE_PRINTF("[BX+DI]"); return M.x86.R_BX + M.x86.R_DI; case 2: DECODE_PRINTF("[BP+SI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI; case 3: DECODE_PRINTF("[BP+DI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI; case 4: DECODE_PRINTF("[SI]"); return M.x86.R_SI; case 5: DECODE_PRINTF("[DI]"); return M.x86.R_DI; case 6: offset = fetch_word_imm(); DECODE_PRINTF2("[%04x]", offset); return offset; case 7: DECODE_PRINTF("[BX]"); return M.x86.R_BX; } HALT_SYS(); return 0;}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=01 addressing. Also enables thedecoding of instructions.****************************************************************************/unsigned decode_rm01_address( int rm){ int displacement;#ifdef ADD_PREFIX_ADDR{ u32 *rp; int ss,index,base; u32 basereg,indexreg; if (M.x86.mode & SYSMODE_PREFIX_ADDR) { M.x86.mode &=~ SYSMODE_PREFIX_ADDR; if(rm==4){//means a SIB follows the ModR/M byte FETCH_DECODE_SIB(ss, index, base);//fetch SIB byte displacement = (s8)fetch_byte_imm(); DECODE_PRINTF2("%x[",displacement); rp=decode_rm_long_register(base); basereg=*rp; if(index!=4){//Scaled Index==5 means none index DECODE_PRINTF("+"); rp=decode_rm_long_register(index); indexreg=*rp; if(ss!=0) DECODE_PRINTF2("*%x",1<<ss); indexreg*=(1<<ss); //mutilply scaled field }else indexreg=0; DECODE_PRINTF("]"); return( displacement+basereg+indexreg ); }else{ displacement = (s8)fetch_byte_imm(); DECODE_PRINTF2("%x[",displacement); rp = decode_rm_long_register(rm); DECODE_PRINTF("]"); return (*rp+displacement); } }}#endif displacement = (u8)fetch_byte_imm(); switch (rm) { case 0: DECODE_PRINTF2("%d[BX+SI]", displacement); return M.x86.R_BX + M.x86.R_SI + displacement; case 1: DECODE_PRINTF2("%d[BX+DI]", displacement); return M.x86.R_BX + M.x86.R_DI + displacement; case 2: DECODE_PRINTF2("%d[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_SI + displacement; case 3: DECODE_PRINTF2("%d[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + M.x86.R_DI + displacement; case 4: DECODE_PRINTF2("%d[SI]", displacement); return M.x86.R_SI + displacement; case 5: DECODE_PRINTF2("%d[DI]", displacement); return M.x86.R_DI + displacement; case 6: DECODE_PRINTF2("%d[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return M.x86.R_BP + displacement; case 7: DECODE_PRINTF2("%d[BX]", displacement); return M.x86.R_BX + displacement; } HALT_SYS(); return 0; /* SHOULD NOT HAPPEN */}/****************************************************************************PARAMETERS:rm - RM value to decodeRETURNS:Offset in memory for the address decodingREMARKS:Return the offset given by mod=10 addressing. Also enables thedecoding of instructions.****************************************************************************/unsigned decode_rm10_address( int rm){ unsigned displacement;#ifdef ADD_PREFIX_ADDR{ u32 *rp; int ss,index,base; u32 basereg,indexreg; if (M.x86.mode & SYSMODE_PREFIX_ADDR) { M.x86.mode &=~ SYSMODE_PREFIX_ADDR; if(rm==4){//means a SIB follows the ModR/M byte FETCH_DECODE_SIB(ss, index, base);//fetch SIB byte displacement = (s32)fetch_long_imm(); DECODE_PRINTF2("%x[",displacement); rp=decode_rm_long_register(base); basereg=*rp; if(index!=4){//Scaled Index==5 means none index DECODE_PRINTF("+"); rp=decode_rm_long_register(index); indexreg=*rp; if(ss!=0) DECODE_PRINTF2("*%x",1<<ss); indexreg*=(1<<ss); //mutilply scaled field }else indexreg=0; DECODE_PRINTF("]"); return( displacement+basereg+indexreg ); }else{ displacement = (s32)fetch_long_imm(); DECODE_PRINTF2("%x[",displacement); rp = decode_rm_long_register(rm); DECODE_PRINTF("]"); return (*rp+displacement); } }}#endif displacement = (u16)fetch_word_imm(); switch (rm) { case 0: DECODE_PRINTF2("%d[BX+SI]", displacement); return (M.x86.R_BX + M.x86.R_SI + displacement); case 1: DECODE_PRINTF2("%d[BX+DI]", displacement); return (M.x86.R_BX + M.x86.R_DI + displacement); case 2: DECODE_PRINTF2("%d[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return (M.x86.R_BP + M.x86.R_SI + displacement); case 3: DECODE_PRINTF2("%d[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return (M.x86.R_BP + M.x86.R_DI + displacement); case 4: DECODE_PRINTF2("%d[SI]", displacement); return (M.x86.R_SI + displacement); case 5: DECODE_PRINTF2("%d[DI]", displacement); return (M.x86.R_DI + displacement); case 6: DECODE_PRINTF2("%d[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; return (M.x86.R_BP + displacement); case 7: DECODE_PRINTF2("%d[BX]", displacement); return (M.x86.R_BX + displacement); } HALT_SYS(); return 0; /*NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -