ESP是否与EAX一样通用?

Dou*_*las 3 x86 assembly cpu-registers

在x86架构中,可以做什么EAX但不能用ESP?忘了pushpopcall.

Pet*_*des 10

ESP被中断隐式地异步使用.在现代操作系统中,它仅适用于内核堆栈,而不适用于用户空间堆栈.内核代码总是需要在启用中断时保持ESP有效,并假设在每条指令之后它下面的空间都被破坏了.

在用户空间中主要(仅?)异步使用ESP是信号处理程序,因此没有信号处理程序的进程不应该异步使用ESP.(你甚至可以为内核设计一个新的ABI,以提供不强制使用ESP的信号).

因此,在某些情况下,用户空间代码可以在关键循环使用ESP作为第8个GP寄存器,否则必须泄漏某些内容,但正如该文章指出的那样,它使得调试在SEH想要查找的Windows上不太方便有效的堆栈.使用MMX或XMM寄存器来保存/恢复ESP,因为静态存储不是线程安全的,并且堆栈不可用(鸡/蛋问题).理论上的相同论点适用于在64位代码中使用RSP,但除RSP之外的15个reg,并且保证SSE2支持,使得这极不可能值得.

此答案中的其他所有内容同样适用于64位模式下的RSP.


ESP限制作为asm /机器码中的GP寄存器操作数

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.
Run Code Online (Sandbox Code Playgroud)

如果我没记错的话,这是ESP just plain作为操作数不可用的唯一情况.另一个特例是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
Run Code Online (Sandbox Code Playgroud)

值得指出的是,即使与ECX等其他寄存器相比,EAX也有很多特别之处.例如,它是隐含使用stos,cdq并且用作一个操作数mul(这列表不是穷举).还有一个1字节的编码xchg eax, reg (非常适合代码高尔夫,但不是性能!),以及使用imm32(如add eax, imm32vs. add r/m32, imm32)的常见ALU操作.(在线查看这些ALU说明或英特尔指令参考手册的原始PDF - 请参阅标签wiki以获取链接.)

基本8个通用寄存器中唯一一个非"特殊"或由任何通用指令隐式使用的是EBX.有关x86寄存器及其名称来自/传统用途的更多信息,请访问http://www.swansontec.com/sregisters.html

  • ebx以前很特殊,它是三个可用于16位代码的存储操作数的寄存器之一。 (2认同)