所以最近我一直想从程序集调用一些win32调用,而且我一直在使用NASM作为我的外部汇编程序。我通过以下方式在代码中调用SendMessage
:
call __imp__SendMessageW@16
这被组装成相对跳转(0xE8操作码),结果是访问冲突。在调试器中,计算出的跳转偏移似乎是正确的(因为__imp__SendMessageW@16
确实似乎存在于那里)但是它没有用。当我从C ++调用函数时检查由Visual Studio生成的程序集,我注意到它不是它正在使用的相对立即跳转,而是(在MASM的语言中)call dword ptr [__imp__SendMessageW@16]
,对应于0xFF15操作码。在经历了一些困难之后,我发现NASM语法将其编码为call dword near [dword __imp__SendMessageW@16]
,并且我的代码突然变了。
我的问题是,为什么一个工作而另一个工作?是否有一些代码重新定位导致相对立即调用跳转到不友好的地方?我从来都不是一个汇编程序员,但我的印象总是这两个调用应该做同样的事情,主要区别在于一个是位置独立而另一个不是(假设他们将IP移动到同一个地方) )。代码理论的重新定位是有道理的,但是那么你如何解释调试器显示正确的地址?
另外:此调用中[]
语法背后的逻辑是什么?偏移量仍然是立即数(只是在0xFF15之后立即编码的小端),除了指令获取之外没有内存访问(我倾向于将[]
视为lea
上下文之外的解除引用)。
答案 0 :(得分:1)
call dword[__imp__SendMessageW@16]
_ imp _SendMessageW @ 16是您的导入部分的地址,其中包含API函数的地址。您可以使用方括号来区分(调用此地址存储的地址)