【发布时间】:2009-09-09 13:58:07
【问题描述】:
每个 asm 指令的大小是多少?每条指令占用多少字节? 8个字节?四个用于操作码,四个用于参数?例如,当您在 mov 中有一个操作码和两个参数时会发生什么?它们的内存大小是固定的还是变化的? EIP和这个有什么关系吗,它的值总是加一,完全独立于它通过什么样的指令?
我在阅读 http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames 时问这个问题,我偶然发现 call 指令似乎等同于 push 和 jmp 指令。
call MYFUNCTION
mov my_var, eax
和一样
push [eip + 2];
jmp MYFUNCTION;
mov my_var, eax
当我们将 [eip + 2] 压入堆栈时,我们指向什么值?在“jmp MYFUNCTION”旁边的那一行,mov my_var eax,对吧?
ps:MSVC++ 在第一行标记一个错误,因为它说 eip 未定义。它适用于 eax、esp、ebp 等。我做错了什么?
【问题讨论】:
-
本题与c++无关,故去掉tag。
-
应该是push eip + 2,而不是push [eip + 2]。
-
必须是"push eip + 2",但是这个是无效的——call理论上是等价的,但是你不能做这个简单的转换。
-
你可以(见coding.derkeiler.com/Archive/Assembler/comp.lang.asm.x86/…的例子)但我不知道设计决策的原因是没有mov EAX、EIP指令或类似的东西。
-
当您定义读取 IP 的指令时,您必须准确定义执行每条指令时 IP 的值(第一个操作码字节?下一条指令的第一个字节?什么?在两者之间,在更复杂的指令中?)然后准备永远使用该定义,以实现未来的兼容性。请记住,由于流水线,实际 IP 在这方面没有很好地定义。出于这个原因,明智的架构师会避开指令集中的此类功能,除非用于特定目的(例如调用和 PC 相对寻址)。