gcc 汇编示例

作者在 2010-08-18 01:25:50 发布以下内容
/**
* hello_asm_reg.c -- a demo for printing "Hello, Gcc Inline Assembly World!n" in gcc inline assembly
* */


int main(void)
{
  char *str="Hello, Gcc Inline Assembly World!n";

  __asm__ __volatile__ (
  "pushl %%edx\n"
  "call puts\n"
  :
  :"d"(str)
  );

  return 0;
}
 
基础知识 | 阅读 3346 次
文章评论,共7条
vfdff(作者)
2010-08-18 13:19
1
#include &lt;asm/page.h&gt;<br />
#include &lt;sys/mman.h&gt;<br />
typedef int (*FUNCPTR)(...);<br />
FUNCPTR newFuncList[MAX_FUNC_NUM] = {NULL}; // MAX_FUNC_NUM在TmpReplaceFunc.h中定义赋值<br />
FUNCPTR oldFuncList[MAX_FUNC_NUM] = {NULL};<br />
BYTE g_aucOldFuncInstruct[MAX_FUNC_NUM][6] = {{0}};<br />
int Ulong2ByteArr(BYTE* pucDest, ULONG ulSrc)<br />
{<br />
&nbsp; &nbsp; // 要考虑大小字节序<br />
&nbsp; &nbsp; *pucDest = (BYTE)(ulSrc &amp; 0XFF);<br />
&nbsp; &nbsp; *(pucDest + 1) = (BYTE)((ulSrc &amp; 0XFF00) &gt;&gt; 8);<br />
&nbsp; &nbsp; *(pucDest + 2) = (BYTE)((ulSrc &amp; 0XFF0000) &gt;&gt; 16);<br />
&nbsp; &nbsp; *(pucDest + 3) = (BYTE)((ulSrc &amp; 0XFF000000) &gt;&gt; 24);<br />
<br />
&nbsp; &nbsp; return 0;<br />
}<br />
<br />
unsigned int ChangeProtection(const unsigned int ulAddr, const unsigned int ulLength, const unsigned int ulMode )<br />
{<br />
&nbsp; &nbsp; int iRtn;<br />
&nbsp; &nbsp; unsigned int ulLastPageEnd;<br />
&nbsp; &nbsp; unsigned int ulFirstPageStart;<br />
<br />
&nbsp; &nbsp; /* Find the start address of the page to which the adress belongs to */<br />
&nbsp; &nbsp; ulFirstPageStart = ulAddr - (ulAddr % 4096);<br />
<br />
&nbsp; &nbsp; ulLastPageEnd&nbsp;&nbsp;= ulAddr + ulLength;<br />
&nbsp; &nbsp; ulLastPageEnd += 4096 - (ulLastPageEnd % 4096);<br />
<br />
&nbsp; &nbsp; iRtn = mprotect((void*)ulFirstPageStart, ulLastPageEnd - ulFirstPageStart, ulMode );<br />
&nbsp; &nbsp; //iRtn = mprotect((void*)ulFirstPageStart, 4096, ulMode );<br />
&nbsp; &nbsp; if (0 != iRtn)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;printf(&quot;\r\nCall mprotect fail!\n&quot;);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return FALSE;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; return TRUE;<br />
}<br />
unsigned int ModProtectMemContent(unsigned long*&nbsp;&nbsp;pBaseAddress, \<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; const BYTE* pucInstruContent, unsigned long ulInstruLen)<br />
{<br />
&nbsp; &nbsp; //BYTE aBuf[10];<br />
<br />
&nbsp; &nbsp; if (ChangeProtection((const unsigned int)pBaseAddress, ulInstruLen, PROT_WRITE | PROT_READ | PROT_EXEC) == FALSE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return FALSE;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; // 修改老函数入口处的指令,用上面准备的跳转指令修改<br />
&nbsp; &nbsp; (void)memcpy(pBaseAddress, pucInstruContent, ulInstruLen);<br />
<br />
&nbsp; &nbsp; if (ChangeProtection((const unsigned int)pBaseAddress, ulInstruLen, PROT_READ | PROT_EXEC) == FALSE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return FALSE;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; return TRUE;<br />
}<br />
<br />
//======================================================<br />
<br />
/*<br />
&nbsp; &nbsp;函数名称:ReadProcessMemExt<br />
&nbsp; &nbsp;功能:&nbsp; &nbsp; 完成获取进程内容的功能,是对ReadProcessMemory的扩展<br />
&nbsp; &nbsp;参数:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[in]&nbsp; &nbsp;hProcess,进程句柄<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[in]&nbsp; &nbsp;pBaseAddress,待写内存开始地址<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[in]&nbsp; &nbsp;ulInstruLen,&nbsp;&nbsp;要读取的内容的长度<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[out]&nbsp; &nbsp;pucInstruContent,保存读到的内容<br />
<br />
&nbsp; &nbsp;返回值:成功返回TRUE,失败返回FALSE<br />
 */<br />
unsigned int ReadProcessMemExt(unsigned long*&nbsp;&nbsp;pBaseAddress, \<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; unsigned long ulInstruLen, BYTE* pucInstruContent)<br />
{<br />
&nbsp; &nbsp; //BYTE aBuf[10];<br />
<br />
&nbsp; &nbsp; if (ChangeProtection((const unsigned int)pBaseAddress, ulInstruLen, PROT_WRITE | PROT_READ | PROT_EXEC) == FALSE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return FALSE;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; // 获取指定内存的内容<br />
&nbsp; &nbsp; (void)memcpy(pucInstruContent, pBaseAddress, ulInstruLen);<br />
<br />
&nbsp; &nbsp; if (ChangeProtection((const unsigned int)pBaseAddress, ulInstruLen, PROT_READ | PROT_EXEC) == FALSE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return FALSE;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; return TRUE;<br />
}
vfdff(作者)
2010-08-19 21:20
2
BYTE aBuf[10];<br />
<br />
&nbsp; &nbsp; //printf(&quot;Input pOldFunc = 0x%x, pNewFunc = 0x%x!\n&quot;, pOldFunc, pNewFunc);<br />
<br />
&nbsp; &nbsp; // 说明:由于函数地址在保护区域,不能用普通的修改内存值的方式实现,<br />
&nbsp; &nbsp; //&nbsp; &nbsp;&nbsp; &nbsp; 只能通过系统函数,来改变某个进程的内存内容方式实现<br />
<br />
&nbsp; &nbsp; // 先得到原函数调用地址的跳转偏移,为下面计算相对偏移做准备<br />
<br />
&nbsp; &nbsp; // 将新函数指针和原函数调用地址保存到列表中<br />
&nbsp; &nbsp; for (i = 0; i &lt; MAX_FUNC_NUM; i++)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (newFuncList<i> == NULL)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;break;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp; } // end for i<br />
<br />
&nbsp; &nbsp; if (i &gt;= MAX_FUNC_NUM)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;printf(&quot;\r\nThe new func list is full!\n&quot;);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return 1;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; // 获取原函数开始的一段指令<br />
<br />
&nbsp; &nbsp; iTmpLen = GetInstructionLen((BYTE*)pOldFunc);<br />
&nbsp; &nbsp; if (0 == iTmpLen)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;printf(&quot;\r\nGen first Instruction length fail!\n&quot;);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return 1;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; else if (iTmpLen &gt;= 5) // &gt;=要插入的跳转指令的长度,只需记录指令长度即可<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;iInstruLen = iTmpLen;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; else<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;iInstruLen = iTmpLen;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;while (iInstruLen &lt; 5)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;iTmpLen = GetInstructionLen((BYTE*)pOldFunc + iInstruLen);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (0 == iTmpLen)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; printf(&quot;\r\nGen other Instruction length fail!\n&quot;);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; return 1;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;iInstruLen += iTmpLen;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; printf(&quot;\r\nThe new func list is %d,!\n&quot;, iInstruLen);
vfdff(作者)
2010-08-22 20:25
3
int puts(char *buf)<br />
{<br />
&nbsp; &nbsp; &nbsp; &nbsp; return 0;<br />
}<br />
<br />
int main(void)<br />
{<br />
&nbsp;&nbsp;char *str=&quot;Hello, Gcc Inline Assembly World!n&quot;;<br />
<br />
&nbsp;&nbsp;puts(str);<br />
<br />
&nbsp;&nbsp;return 0;<br />
}<br />
发现定义一个和库函数同名的函数,则库函数被隐藏,并且不提示函数冲突错误
vfdff(作者)
2010-11-10 12:57
4
// 找出只包含ModR/M,不包含立即数的指令操作码<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x00:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// LLDT/LTR/SLDT/STR/VERR/VERW<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x01:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// INVLPG/LGDT/LIDT/LMSW/SGDT/SIDT/SMSW/SMSW<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x02:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// LAR<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x03:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// LSL<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x20:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x21:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x22:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x23:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// MOV (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x40:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVO (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x41:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNO (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x42:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVB/CMOVC/CMOVNAE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x43:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNB/CMOVNC/CMOVAE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x44:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVE/CMOVZ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x45:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNE/CMOVNZ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x46:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVBE/CMOVNA (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x47:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNBE/CMOVA (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x48:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVS (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x49:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNS (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x4A:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVP/CMOVPE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x4B:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNP/CMOVPO (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x4C:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVL/CMOVNGE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x4D:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNL/CMOVGE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x4E:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVLE/CMOVNG (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x4F:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMOVNLE/CMOVG (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x60:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PUNPCKLBW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x61:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PUNPCKLWD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x62:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PUNPCKLDQ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x63:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PACKSSWB&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x64:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PCMPGTB&nbsp; &nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x65:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PCMPGTW&nbsp; &nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x66:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PCMPGTD&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x67:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PACKUSWB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x68:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PUNPCKHBW(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x69:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PUNPCKHWD(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x6A:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PUNPCKHDQ(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x6B:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PACKSSDW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x6E:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// MOVD&nbsp; &nbsp;&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x6F:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// MOVQ&nbsp; &nbsp;&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x74:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PCMPEQB&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x75:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PCMPEQW&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x76:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PCMPEQD&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x7E:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// MOVD&nbsp; &nbsp;&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x7F:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// MOVQ&nbsp; &nbsp;&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x90:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETO<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x91:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNO<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x92:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETB/SETC/SETNAE<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x93:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETAE/SETNB/SETNC<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x94:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETE/SETZ<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x95:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNE/SETNZ<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x96:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETBE/SETNA<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x97:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNBE/SETA<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x98:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x99:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x9A:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETP/SETPE<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x9B:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNP/SETPO<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x9C:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETL/SETNGE<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x9D:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNL/SETGE<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x9E:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETLE/SETNG<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x9F:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SETNLE/SETG<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xA3:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BT<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xA5:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SHLD<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xAB:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BTS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xAD:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SHRD<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xAF:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// IMUL<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB0:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB1:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// CMPXCHG<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB2:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// LSS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB3:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BTR<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB4:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// LFS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB5:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// LGS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB6:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xB7:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// MOVZX<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xBB:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BTC<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xBC:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BSF<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xBD:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BSR<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xBE:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xBF:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// MOVSX<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xC0:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xC1:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// XADD<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xD1:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSRLW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xD2:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSRLD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xD3:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSRLQ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xD5:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PMULLW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xD8:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBUSB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xD9:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBUSW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xDB:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PAND (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xDC:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDUSB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xDD:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDUSW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xDF:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PANDN (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xE1:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSRAW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xE2:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSRAD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xE5:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PMULHW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xE8:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBSB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xE9:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBSW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xEB:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// POR (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xEC:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDSB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xED:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDSW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xEF:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PXOR (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xF1:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSLLW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xF2:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSLLD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xF3:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSLLQ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xF5:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PMADDWD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xF8:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xF9:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xFA:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSUBD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xFC:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDB (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xFD:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xFE:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PADDD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;ulAnlysFlag |= FLAG_MOD_RM;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;break;
vfdff(作者)
2010-11-10 12:58
5
//-----------------------------------------------<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// 找出包含ModR/M和操作数为一字节立即数的指令操作码<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x71:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSLLW/PSRAW/PSRLW (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x72:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSLLD/PSRAD/PSRLD (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;x73:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// PSLLQ/PSRLQ&nbsp;&nbsp;(new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xA4:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SHLD<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xAC:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// SHRD<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;xBA:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// BT/BTC/BTR/BTS<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;ulDataLen++;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;ulAnlysFlag |= FLAG_MOD_RM;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;break;
vfdff(作者)
2010-11-10 13:00
6
//------------------------------------------------<br />
&nbsp; &nbsp; &nbsp; &nbsp; // 找出包含ModR/M和操作数为默认长度立即数的指令操作码<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x80:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JO (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x81:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JNO (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x82:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JB/JC/JNAE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x83:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JAE/JNB/JNC (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x84:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JE/JZ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x85:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JNE/JNZ (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x86:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JBE/JNA (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x87:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JA/JNBE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x88:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JS (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x89:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JNS (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x8A:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JP/JPE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x8B:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JNP/JPO (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x8C:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JL/JNGE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x8D:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JGE/JNL (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x8E:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JLE/JNG (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0x8F:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// JG/JNLE (new)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;ulDataLen += ulDefOprdSize;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;break;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//-----------------------------------------------<br />
&nbsp; &nbsp; &nbsp; &nbsp; // 对CMPXCHG8B指令特殊处理<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;case 0xC7:&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// CMPXCHG8B<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;ulDataLen++;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;break;<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//----------------------------------<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;default:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;InfoOutput(&quot;\r\n[EXPT]The second opcode is 0x%X when first opcode is 0x0F, not support!&quot;, ucOpcode2);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;return 0;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// 0F 第二个操作码为其他取值的,认为出错了,返回0<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}&nbsp; &nbsp;&nbsp;&nbsp;// 0F-switch<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;break;<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// 目前不支持操作码为82/D6/F1的指令,如果出现了,说明出现异常<br />
&nbsp; &nbsp; case 0x82:<br />
&nbsp; &nbsp; case 0xD6:<br />
&nbsp; &nbsp; case 0xF1:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;InfoOutput(&quot;\r\n[EXPT]The Opcode is 0x%X, not support!&quot;, ucOpcode);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return 0;<br />
&nbsp; &nbsp; } //switch<br />
<br />
&nbsp; &nbsp; if (ulAnlysFlag &amp; FLAG_MOD_RM)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;// 得到ModR/M字节的内容<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ucModRM = *pucTmpInstruAddr++;<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/*<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;ModR/M字节的结构如下:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;+----+------+------+<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|mod | reg2 | reg1 |<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;+----+------+------+<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;*/<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ucMod = ucModRM &amp; 0xC0; // 得到ModR/M字节mod域的取值<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ucRM = ucModRM &amp; 0x07; // 得到ModR/M字节reg1域的取值<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (ucMod != 0xC0) // 后续的为内存地址而非寄存器<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (ucMod == 0x40) // mod = 01, 则后面用一字节的空间来存放偏移<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ulAddrLen++;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;else if (ucMod == 0x80) // mod = 10, 则后面用一个机器字(即默认地址长度)的空间来存放偏移<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ulAddrLen += ulDefAddrSize;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if (ulDefAddrSize == 2) // modrm16<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; if ((ucMod == 0x00) &amp;&amp; (ucRM == 0x06)) // mod = 00, reg1 = 6,且为16bit模式,后面用2个字节来保存偏移<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ulAddrLen += 2;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; }<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;else // modrm32<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; if (ucRM == 0x04)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ulAnlysFlag |= FLAG_SIB;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ucSIB = *pucTmpInstruAddr++;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; }<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; else if ((ucRM == 0x05) &amp;&amp; (ucMod == 0x00)) // mod = 00, reg1 = 5,且为32bit模式,后面用4个字节来保存偏移<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ulAddrLen += 4;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; }<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;} // end of if(ucMod != 0xC0)<br />
&nbsp; &nbsp; } // end of if(ulAnlysFlag &amp; FLAG_MOD_RM)<br />
<br />
&nbsp; &nbsp; // 得到指令的长度<br />
&nbsp; &nbsp; iInstruLen&nbsp;&nbsp;= pucTmpInstruAddr - pucInstruAddr;<br />
&nbsp; &nbsp; iInstruLen += ulAddrLen;<br />
&nbsp; &nbsp; iInstruLen += ulDataLen;<br />
<br />
&nbsp; &nbsp; return iInstruLen;<br />
} // end of func GetInstructionLen
vfdff(作者)
2010-11-11 00:11
7
gcc 内嵌汇编的编码示例<br />
<br />
Linux 内核源代码中,许多C 代码中嵌入了汇编语句,这是通过关键字asm 来实现的。<br />
<br />
它的形式如下所示:<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 代码片段2.6 gcc 内嵌汇编示例<br />
--------------------------------------------------------------------------------------------<br />
<br />
1 static inline unsigned long native_read_cr2(void) <br />
2 { <br />
3 unsigned long val; <br />
4 asm volatile(&quot;movl %%cr2,%0\n\t&quot; :&quot;=r&quot; (val)); <br />
5 return val; <br />
6 } <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;其中asm 表示汇编指令的开始,由于gcc 在编译优化阶段,可能会调整指令的顺序,关键字volatile 阻止gcc 对这里的内嵌汇编指令进行优化。另外在内核代码中常常还看到__asm__,__volatile__,它们的作用和asm,volatile 是一样的,为什么要两个作用相同的关键字呢?这是由于在C 标准制定之初,并没有asm 和volatile 这两个关键字,后来由于实际需要,加入了这两个关键字时,考虑到已有的C 代码中,可能存在变量名为asm 或volatile 的情况,为了兼容这种情况,所以又加入了__asm__ 和__volatile__ 这两个关键字。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;gcc 内嵌汇编的通用形式如下所示:<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;代码片段2.7 Intel 与AT&amp;T 汇编格式比较<br />
--------------------------------------------------------------------------------------------<br />
<br />
1 asm volatile (assembler template : output : input: clobber); <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;其中assembler template 为汇编指令部分,例如上例中的&quot;movl %%cr2, %0&quot;。output 是输出部分,input 表示输入部分,clobber 表示被修改的部分。汇编指令中的数字和前缀%表示样板操作数,例如%0,%1 等,用来依次指代后面的输出部分,输入部分等样板操作数。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;由于这些样板操作数使用了%,因此寄存器前面要加两个%,例如上例中的%%cr2。ouput 和input 分别是输出部分和输入部分,clobber 是损坏部分。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;为什么要这样呢?这是由于汇编指令中常常需要使用寄存器,但是寄存器是由gcc 在编译时分配的,由于访问寄存器要比访问内存快,因此当gcc 对一个代码块进行优化时,通常把空闲的寄存器分配给被频繁访问的变量。假设有以下代码块:<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 代码片段2.8 C 代码示例<br />
--------------------------------------------------------------------------------------------<br />
<br />
1 int f()<br />
2 {<br />
3 ....<br />
4 int i;<br />
5 int total = 0;<br />
6 for (i = 0; i &lt; 100; i++) {<br />
7 <br />
8 <br />
9 <br />
10 <br />
11 <br />
total += i; <br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;} <br />
... <br />
return total; <br />
} <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;在上面的代码块中,i 和total 都是被频繁访问的变量,因此gcc 可能会为它们分配两个空闲的寄存器,例如把EAX 和ECX 分别分配给i 和total,这样在整个for 循环只需要对寄存器进行操作。如果在for 循环之前所有的寄存器已经分配出去了,此时就没有空闲的寄存器,gcc 可能需要插入一条指令把某个寄存器的值写回到对应的内存变量中(和前面的EAX 对应于堆栈中的一个内存变量i 是一样的道理),然后再把这个寄存器分配给变量i。需要注意的是,这里讨论的是有这种可能。因此程序员在任何时候都不知道哪个寄存器是空闲的。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;我们再来看一个例子,汇编指令bts n, ADDR ,可以把地址为ADDR 的内存单元的第n 位设置为1。其中ADDR 是一个内存变量,而n 必须是立即数或寄存器。如果要在C 代码中之间嵌入这条汇编指令,而n 是通过计算得到的结果(n 不是立即数),这时就需要腾出一个寄存器来。而程序员不能预测到gcc 在编译时对寄存器的分配情况,所以gcc 的内嵌汇编提供一个模板,用来指导gcc 该如何处理。下面是在C 代码中内嵌btsl 指令的示例。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;代码片段2.9 gcc 内嵌汇编代码示例<br />
--------------------------------------------------------------------------------------------<br />
<br />
1 static inline void set_bit(int nr, void *addr)<br />
2 {<br />
3 asm(&quot;btsl %1,%0&quot; : &quot;+m&quot; (*(u32 *)addr) : &quot;Ir&quot; (nr));<br />
4 }<br />
<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;在这个例子中输出部分为addr,输入部分为nr,没有损坏部分。修饰符&quot;+m&quot;限定指针addr 指向一个可读写的内存单元,&quot;Ir&quot;指定nr 必须是一个立即数,或者是一个寄存器变量。<br />
<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;当某段代码调用set_bit()函数时,如果参数nr 是一个立即数或者是一个寄存器,那么就满足这个限制条件。但是如果调用set_bit()函数时传递的参数nr 在内存中,这时候gcc 必须分配一个寄存器,并且插入一条指令把内存中的值加载到这个寄存器中。如果没有空闲的寄存器,那么gcc 就要插入一条指令把某个寄存器保存到对应的内存中,腾出这个寄存器来保存参数nr 的值,最后再插入一条指令恢复这个寄存器的值。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;在指令部分中的%0 表示addr 对应的操作数,%1 表示nr 对应的操作数。现在假设某段代码调用set_bit()函数时传递的参数nr 内存变量,gcc 在代码生成阶段,生成类似下面这样的代码2: <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;代码片段2.10 汇编代码<br />
--------------------------------------------------------------------------------------------<br />
<br />
1 # 腾出EAX 寄存器。<br />
<br />
&nbsp; &nbsp;注意这个例子的目的是为了说明原理,实际试验时不一定能够得到一模一样的结果。<br />
<br />
2.2 gcc 内嵌汇编23 <br />
2 pushl %eax; <br />
3 movl nr, %eax; <br />
4 <br />
5 # 假设(ebp-8)就是指针addr 指向的内存单元地址。<br />
6 bts %eax, -8(ebp); <br />
7 <br />
8 # 恢复EAX 寄存器。<br />
9 popl %eax <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;通过这个例子就可以理解gcc 内嵌汇编复杂的原因了,在理解这个例子后,再来看gcc 的内嵌汇编,也就简单得多了。在gcc 内嵌汇编中,常用的限制符如表2.1所示。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;现在来看一个相对复杂的例子,代码片段2.11 gcc 内嵌汇编代码示例<br />
____________________________________________________________________<br />
<br />
1 #define mov_blk(src, dest, numwords)<br />
2 __asm__ __volatile__ (<br />
3 &quot;cld\n\t&quot;<br />
4 &quot;rep\n\t&quot;<br />
5 &quot;movsl&quot;<br />
6 : <br />
7 : &quot;S&quot; (src), &quot;D&quot; (dest), &quot;c&quot; (numwords) <br />
8 :&quot;%ecx&quot;, &quot;%esi&quot;, &quot;%edi&quot; <br />
9 ) <br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;我们知道,串操作指令movs 可以把ESI 寄存器指向的内存块复制到EDI 指向的内存块中,复制的字节数由ECX 寄存器指定。所以执行rep movsl 之前需要初始化ESI,EDI 和ECX 寄存器,但是在上面这段代码的汇编指令部分中,并没有看到设置这几个寄存器的汇编指令。这是由gcc 自动完成的。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;在输入参数部分&quot;S&quot;(src)指定参数src 必须保存到ESI 寄存器中,&quot;D&quot;(dest)指定参数dest 必须保存到EDI 中,&quot;c&quot;(numwords)指定参数numwords 必须保存到ECX 中。在gcc 的代码生成阶段,在调用mov_blk()这个宏的代码块中,如果参数src,dest,numwords 都没有分配到对应的寄存器中,那么gcc 在展开汇编指令部分最前面插入指令,保存相应的寄存器,并且把参数src,dest,numwords 复制到对应的寄存器中。如果在此之前正好某个参数已经被gcc 分配到对应的寄存器中,那么就不需要插入这样的汇编指令。<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;在损坏部分,&quot;%ecx&quot;,&quot;%esi&quot;,&quot;%edi&quot;说明在汇编指令部分会改变这几个寄存器的值,这样如果之前这几个寄存器被分配给其他的变量,在代码前面gcc 会插入汇编指令保存这几个寄存器,在代码的最后,gcc 又会插入代码恢复这几个寄存器的值。<br />
<br />
本文摘自《独辟蹊径品内核:Linux内核源代码导读》
游客请输入验证码
浏览1936543次