为什么装配看起来不一致?

时间:2010-10-12 13:35:41

标签: c++ visual-studio assembly

从视觉工作室倾销:

    CheckPointer(pReceivePin,E_POINTER);
017D616D  cmp         dword ptr [ebp+0Ch],0 
017D6171  jne         CBasePin::Connect+4Dh (17D617Dh) 
017D6173  mov         eax,80004003h 
017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h) 

但实际定义是:

#define CheckPointer(p,ret) {if((p)==NULL) return (ret);}

虽然我的装配不太好,但我发现源和asm之间没有任何关系。

4 个答案:

答案 0 :(得分:3)

你已经遗漏了很多东西,很难确定,但可以整理的部分看起来很合理。 NULL == 0,所以:

017D616D  cmp         dword ptr [ebp+0Ch],0               ; if [ebp+0ch] == 0
017D6171  jne         CBasePin::Connect+4Dh (17D617Dh)    ;     goto 172617dh
017D6173  mov         eax,80004003h                       ; else load 'ret'
017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h)   ;     and return it.

显而易见的问题是你没有向我们展示17D617Dh或17D62D7h的内容,所以我们无法真正猜测这些值的真正含义。

答案 1 :(得分:0)

可能的

 CheckPointer(pReceivePin,E_POINTER);
 017D616D  cmp         dword ptr [ebp+0Ch],0 
 017D6171  jne         CBasePin::Connect+4Dh (17D617Dh) 
 017D6173  mov         eax,80004003h 
 017D6178  jmp         CBasePin::Connect+1A7h (17D62D7h) 

pReceivePin恰好位于存储在堆栈上的地址 - 通常使用ebp中的值存储通过间接访问。

将该值与null进行比较,如果该值为null(jne未启动),则E_POINTER的实际值将移至eaxeax为用于存储函数的返回值),控件被传递给函数结尾,在那里进行清理,然后将控制权返回给调用者(ret指令)。如果pReceivePin的值不为空(jne确实启动),则控制权将传递到其他位置,其中存储了恰好位于CheckPointer之后的代码,然后执行该代码。

答案 2 :(得分:0)

你需要提供更多的上下文,但很可能,最后一行跳转到CBasePin :: Connect函数的最终部分,紧接着是RET。它与宏的逻辑非常一致。如果指针不为零(即空值),则第二行在最后一行之后跳转。

答案 3 :(得分:0)

装配看起来非常好。

cmp dword ptr [ebp+0Ch],0pReceivePinNULL的比较。 pReceivePin是函数内部的局部变量,因此它的地址是函数堆栈帧开头的偏移量。 ebp保存堆栈帧开头的地址。 0Ch是堆栈帧内pReceivePin的偏移量。除参数外,函数中的所有局部变量都将作为[ebp + something]进行寻址。参数通常表示为[ebp - something]

mov eax,80004003h只是放入函数“返回值”区域的E_POINTER值(寄存器eax用于此目的)。

最终jmp将控制权发送到当前函数(CBasePin::Connect)的结尾代码,该代码以ret命令结束(并“返回”当前eax值,即E_POINTER

如果jne不等于pReceivePin,则会立即对您的宏后代码E_POINTER进行敏感控制。