从视觉工作室倾销:
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之间没有任何关系。
答案 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
的实际值将移至eax
(eax
为用于存储函数的返回值),控件被传递给函数结尾,在那里进行清理,然后将控制权返回给调用者(ret
指令)。如果pReceivePin
的值不为空(jne
确实启动),则控制权将传递到其他位置,其中存储了恰好位于CheckPointer
之后的代码,然后执行该代码。
答案 2 :(得分:0)
你需要提供更多的上下文,但很可能,最后一行跳转到CBasePin :: Connect函数的最终部分,紧接着是RET。它与宏的逻辑非常一致。如果指针不为零(即空值),则第二行在最后一行之后跳转。
答案 3 :(得分:0)
装配看起来非常好。
cmp dword ptr [ebp+0Ch],0
是pReceivePin
与NULL
的比较。 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
进行敏感控制。