---->就问你几个问题:
本文译自Intel 64 And IA-32 Architectures Software Developer’s Manual Volume 2 Instruction Set Reference
文档最初写在我的WORD文档,存在网盘里,发表到优快云博客时有改动
http://pan.baidu.com/s/1bnm4g6z
PUSH—Push Word, Doubleword or Quadword Onto the Stack
PUSH指令,把字,双字或四字压入堆栈
(译者注: 毫不客气地透漏下,我根本看不懂这是什么意思,待日后看懂后修改本篇文档)
指令描述Description
Decrements the stack pointer and then stores the source operand on the top of the stack. Address and operand sizes are determined and used as follows:
递减栈顶指针,然后将源操作数存到栈顶。地址和操作数位数的确定和使用规则如下:
• Address size. The D flag in the current code-segment descriptor determines the default address size; it may be overridden by an instruction prefix (67H).
地址位数。在当前代码段描述符中的D标志决定了默认的地址位数;地址位数也能由指令前缀67H翻转。
The address size is used only when referencing a source operand in memory.
地址位数只在引用在内存中的源操作数时才会使用。
• Operand size. The D flag in the current code-segment descriptor determines the default operand size; it may be overridden by instruction prefixes (66H or REX.W).
操作数位数。在当前代码段描述符中的D标志决定了默认的操作数位数;操作数位数也能被指令前缀翻转(66H 或 REX.W )
The operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is decremented (2, 4 or 8).
操作数位数(16, 32 或64位)决定了栈顶指针的减量(2, 4, 或 8 )。
If the source operand is an immediate of size less than the operand size, a sign-extended value is pushed on the stack. If the source operand is a segment register (16 bits) and the operand size is 64-bits, a zero extended value is pushed on the stack; if the operand size is 32-bits, either a zero-extended value is pushed on the stack or the segment selector is written on the stack using a 16-bit move. For the last case, all recent Core and Atom processors perform a 16-bit move, leaving the upper portion of the stack location unmodified.
如果源操作数是小于操作数位数的立即数,压入堆栈的是带符号拓展补位的立即数。如果源操作数是段寄存器(16位大小)而操作数位数是64位的,压入堆栈的是用零拓展补位的段寄存器值; 若操作数位数是32位的,或者用0补位压栈,或者将段选择子使用16位的传送指令写到栈顶。对于后一种情况,所有最近推出的酷睿和安腾处理器使用其余位不动地16位传送.
• Stack-address size. Outside of 64-bit mode, the B flag in the current stack-segment descriptor determines the size of the stack pointer (16 or 32 bits); in 64-bit mode, the size of the stack pointer is always 64 bits.
栈地址位数。除64位模式外,当前堆栈段描述符的B标志决定了栈顶指针(16或32位);在64位模式里,栈顶指针永远是64位。
The stack-address size determines the width of the stack pointer when writing to the stack in memory and
when decrementing the stack pointer. (As stated above, the amount by which the stack pointer is decremented is determined by the operand size.)
栈地址位数在向内存中的栈写数据和递减栈顶指针时候决定了栈顶指针的宽度。(如上所述,栈顶指针减少了量由操作数位数决定。)
If the operand size is less than the stack-address size, the PUSH instruction may result in a misaligned stack pointer (a stack pointer that is not aligned on a doubleword or quadword boundary).
若操作数位数少于栈地址位数,PUSH指令会导致栈顶指针不对齐(栈顶指针在双字或四字边界不对齐)。
The PUSH ESP instruction pushes the value of the ESP register as it existed before the instruction was executed. If a PUSH instruction uses a memory operand in which the ESP register is used for computing the operand address, the address of the operand is computed before the ESP register is decremented.
PUSH ESP把指令执行前的ESP寄存器压栈。若PUSH指令使用ESP寄存器用来计算操作数地址的内存操作数,操作数的地址在ESP寄存器递减前被计算。
If the ESP or SP register is 1 when the PUSH instruction is executed in real-address mode, a stack-fault exception (#SS) is generated (because the limit of the stack segment is violated). Its delivery encounters a second stack fault exception (for the same reason), causing generation of a double-fault exception (#DF). Delivery of the double-fault exception encounters a third stack-fault exception, and the logical processor enters shutdown mode. See the discussion of the double-fault exception in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.
若ESP或SP寄存器在实模式下执行后是1,栈故障异常(#SS)就会产生(因为违背了设置的段界限)。如果巧合的话,产生了第二个栈故障错误(原因相同),会产生双重故障异常(#DF)。若再遇到第三个栈故障错误,逻辑处理器会进入关机模式。关于双重故障异常我们在Intel(R) 64与IA-32架构软件开发者手册,第三卷中讨论。
IA-32架构兼容性IA-32 Architecture Compatibility
For IA-32 processors from the Intel 286 on, the PUSH ESP instruction pushes the value of the ESP register as it existed before the instruction was executed. (This is also true for Intel 64 architecture, real-address and virtual-8086 modes of IA-32 architecture.) For the Intel® 8086 processor, the PUSH SP instruction pushes the new value of the SP register (that is the value after it has been decremented by 2).
对于Intel 286以后的IA-32架构处理器,PUSH ESP指令将执行前的ESP压栈。(同样适用于Intel 64架构和IA-32架构上的虚拟8086模式。)对于Intel® 8086处理器,PUSH SP把执行后的SP新值压栈(即SP减2后的值)。
Intel官方伪指令描述的操作Operation
(* See Description section for possible sign-extension or zero-extension of source operand and for *)
(* a case in which the size of the memory store may be smaller than the instruction’s operand size *)
IF StackAddrSize = 64
THEN
IF OperandSize = 64
THEN
RSP ←RSP – 8;
Memory[SS:RSP] ←SRC; (* push quadword *)
ELSE IF OperandSize = 32
THEN
RSP ←RSP – 4;
Memory[SS:RSP] ←SRC; (* push dword *)
ELSE (* OperandSize = 16 *)
RSP ←RSP – 2;
Memory[SS:RSP] ←SRC; (* push word *)
FI;
ELSE IF StackAddrSize = 32
THEN
IF OperandSize = 64
THEN
ESP ←ESP – 8;
Memory[SS:ESP] ←SRC; (* push quadword *)
ELSE IF OperandSize = 32
THEN
ESP ←ESP – 4;
Memory[SS:ESP] ←SRC; (* push dword *)
ELSE (* OperandSize = 16 *)
ESP ←ESP – 2;
Memory[SS:ESP] ←SRC; (* push word *)
FI;
ELSE (* StackAddrSize = 16 *)
IF OperandSize = 32
THEN
SP ←SP – 4;
Memory[SS:SP] ←SRC; (* push dword *)
ELSE (* OperandSize = 16 *)
SP ←SP – 2;
Memory[SS:SP] ←SRC; (* push word *)
FI;
FI;
标志位影响状况Flags Affected
None.
无影响
保护模式下能够产生的异常Protected Mode Exceptions
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#GP(0)若内存操作数的实际地址超出CS, DS, ES, FS, GS的段界限。
If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector.
在DS, ES, FS, GS寄存器用来访问内存并且寄存器本身包含NULL选择子。
#SS(0) If a memory operand effective address is outside the SS segment limit.
#SS(0)若内存操作数的实际地址超过SS段界限。
#PF(fault-code) If a page fault occurs.
#PF(故障代码) 如果发生页故障。
#AC(0)If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3
#AC(0) 若启用了对齐检查,并且在当前特权级(CPL)是3时引用了一个没有对齐的内存引用。
#UD If the LOCK prefix is used.
#UD 使用了LOCK指令前缀。
实模式下可能产生的异常Real-Address Mode Exceptions
#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#GP(0)若内存操作数的实际地址超出CS, DS, ES, FS, GS的段界限。
#SS If a memory operand effective address is outside the SS segment limit.
#SS(0)若内存操作数的实际地址超过SS段界限。
If the new value of the SP or ESP register is outside the stack segment limit.
若SP或ESP得到新值超出了堆栈段界限
#UD If the LOCK prefix is used.
#UD 使用了LOCK前缀。
虚拟8086模式下可能产生的异常Virtual-8086 Mode Exceptions
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#GP(0)若内存操作数的实际地址超出CS, DS, ES, FS, GS的段界限。
#SS(0) If a memory operand effective address is outside the SS segment limit.
#SS(0)若内存操作数的实际地址超过SS段界限。
#PF(fault-code) If a page fault occurs.
#PF(故障代码) 如果发生页故障。
#AC(0)If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3
#AC(0) 若启用了对齐检查,并且在当前特权级(CPL)是3时引用了一个没有对齐的内存引用。
#UD If the LOCK prefix is used.
#UD 使用了LOCK指令前缀。
兼容模式可能产生的异常Compatibility Mode Exceptions
Same exceptions as in protected mode.
与保护模式下情况相同
64位模式可能产生的异常64-Bit Mode Exceptions
#GP(0) If the memory address is in a non-canonical form.
#GP(0) 若内存地址使用了不标准的格式
#SS(0) If the stack address is in a non-canonical form.
#SS(0) 若内存地址使用了不标准的格式
#PF(fault-code) If a page fault occurs.
#PF(故障代码) 如果发生页故障。
#AC(0)If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3
#AC(0) 若启用了对齐检查,并且在当前特权级(CPL)是3时引用了一个没有对齐的内存引用。
#UD If the LOCK prefix is used.
#UD 若使用了LOCK指令前缀
If the PUSH is of CS, SS, DS, or ES.
若PUSH了CS, SS, DS 或ES
后记:
英语语法、翻译水平有限,这几句话翻译的很蹩脚,也不知对不对,待日后检验。
1. The PUSH ESP instruction pushes the value of the ESP register as it existed before the instruction was executed.
2. If a PUSH instruction uses a memory operand in which the ESP register is used for computing the operand address, the address of the operand is computed before the ESP register is decremented.
3. If the ESP or SP register is 1 when the PUSH instruction is executed in real-address mode, a stack-fault exception (#SS) is generated (because the limit of the stack segment is violated).
4. #SS(0) If the stack address is in a non-canonical form.