在x86架构中,EAX
可以做什么而ESP
无法做什么?忘记push
和pop
以及call
。
答案 0 :(得分:9)
ESP被中断隐式地异步使用。在现代操作系统中,它仅适用于内核堆栈,而不适用于用户空间堆栈。内核代码总是需要在启用中断时保持ESP有效,并假设在每条指令之后它下面的空间被破坏。
用户空间中ESP的主要(仅?)异步使用是信号处理程序,因此没有信号处理程序的进程不应该异步使用ESP。 (你甚至可以为内核设计一个新的ABI来传递没有强制使用ESP的信号。)
因此,在某些情况下,用户空间代码可以使用using ESP as an 8th GP register in a critical loop,否则必须泄漏某些东西,但正如该文章指出的那样,它使得在SEH想要找到有效堆栈的Windows上调试不太方便。使用MMX或XMM寄存器来保存/恢复ESP,因为静态存储不是线程安全的,并且堆栈不可用(鸡/蛋问题)。理论上的相同论点适用于在64位代码中使用RSP,但除了RSP之外还有15个regs,并且保证SSE2支持,这使得它极不可能值得。
此答案中的其他所有内容同样适用于64位模式下的RSP。
ESP除了其他寄存器之外只能做一件事: ESP不能成为寻址模式下的索引寄存器。
mov edx, [esp + eax*4] ; legal
mov edx, [eax + esp*4] ; not encodeable
mov edx, [eax + esp] ; assemblers will encode this with esp as the base reg, since neither reg is scaled.
如果我没记错的话,这是ESP唯一无法作为操作数使用的唯一情况。另一个特殊情况是ESP作为基址寄存器总是需要一个SIB字节,即使没有索引:
mov edx, [eax] ; 2 bytes: opcode + ModRM
mov edx, [ebp] ; 3 bytes: opcode + ModRM + disp8=0 (the other addressing-mode limitation, ebp/rbp and r13 as a base reg needs a displacement; the mode+M encoding that would mean this actually mean something else)
mov edx, [esp] ; 3 bytes: opcode + ModRM + SIB
mov edx, [ebp + 4] ; 3 bytes: opcode + ModRM + disp8
mov edx, [esp + 4] ; 4 bytes: opcode + ModRM + SIB + disp8
mov edx, [ebp + 4 + eax] ; 4 bytes: opcode + ModRM + SIB + disp8
mov edx, [esp + 4 + eax] ; 4 bytes: opcode + ModRM + SIB + disp8
值得指出的是,即使与ECX等其他寄存器相比,EAX也有很多特别之处。例如,它隐含地与stos
,cdq
一起使用,并作为mul
的操作数(此列表并非详尽无遗)。 xchg eax, reg
(great for code golf but not performance!)还有一个1字节的编码,对于使用imm32的常见ALU操作(如add eax, imm32
与add r/m32, imm32
)。 (查看这些ALU说明online或英特尔指令参考手册的原始PDF - 请参阅x86标记维基以获取链接。)
基本8个通用寄存器中唯一一个不是&#t;#34;特殊的"或任何常见指令隐含使用的是EBX。有关x86寄存器及其名称来自/传统用途的更多信息,请参阅http://www.swansontec.com/sregisters.html