究竟是怎么回事。
我将一个过程的OFFSET
加载到一个寄存器中,然后尝试调用该寄存器:
MOV EBX, OFFSET MyProc
CALL EBX
首先我会假设这会调用该函数,但是当您调用一个不要键入CALL OFFSET MyProc
的过程时,只需键入CALL MyProc
即可。
在C中,您可以使用*
运算符调用指向函数的指针:(*MyProc)();
。
这让我想知道是否取消引用该函数的指针会调用该过程。
CALL [EBX]
但是如果我取消引用它,masm告诉我需要指定一个大小,我可以指定的唯一可能的大小是DWORD PTR
,{{1 }}和WORD PTR
,我并不认为某个程序具有特定的大小。
总结一下,你可以通过直接将指针作为操作数提供给调用指令来调用指向过程的指针,还是必须取消引用调用指令中的指针?
由于
答案 0 :(得分:2)
为什么不CALL OFFSET MyProc
- 因为每次输入都会很烦人,并且不一致的语法对MASM创建者的影响不大(考虑mov eax,var1
vs mov eax,[ebx]
,两者都解除引用内存)。
call [ebx]
将获取存储在ebx
地址的值并将其用作最终目标地址,因此在您的情况下,它会尝试将第一个过程指令解释为目标地址,并跳转为谁-know-where(可能导致操作系统非法访问崩溃)。
在这种情况下,所需的大小不是经典的整数大小,而是跳转/调用地址大小,如NEAR PTR
和FAR PTR
,它会影响内存中将使用多少字节({{1}在32b模式下,32b宽与16b在实模式下(仅偏移部分),NEAR PTR
在实模式下为32b(16b偏移+ 16b段),在32b保护模式下为48b(32b偏移+ 16b段,其中更像是选择器或其他东西,我从来没有真正需要完全理解这个,所以请查阅你最喜欢的x86文档/书籍以获取详细信息。)