《《英特尔64和IA-32架构软件开发人员手册》第2B卷:指令集参考,N-Z >>说:
| Opcode* | Instruction | Op/En | 64-Bit Mode | Compat/Leg Mode | Description |
| 6A | PUSH imm8 | C | Valid | Valid | Push imm8. |
| 68 | PUSH imm16 | C | Valid | Valid | Push imm16. |
| 68 | PUSH imm32 | C | Valid | Valid | Push imm32. |
#cat -n test.asm
1 bits 64
2
3 push byte 12
4 push word 12
5 push dword 12
6 push qword 12
7
#nasm test.asm
test.asm:5: error: instruction not supported in 64-bit mode
为什么第5行是非法的?我认为它与“ PUSH imm32”匹配。
为什么第6行是合法的?它与任何“ PUSH imm8 / PUSH imm16 / PUSH imm32”都不匹配。
请帮帮我!
======测试======
I think that the Intel manual is right, the 'push imm'
instructions do have three encoding form:
Form 1: 6a XX
Form 2: 66 68 XX XX
Form 3: 68 XX XX XX XX
What we are arguing is the implemental specific behavior of the NASM.
In NASM 2.04rc1(the above example I given):
1. The 'byte' in 'push byte imm' direct the NASM use the Form 1,
no matter how long the imm given in the instruction it is, the imm
was trunked to a byte in final machine code.
2. The 'word' in 'push word imm' direct the NASM use the Form 2,
no matter how long the imm given in the instruction it is, the imm
was trucked or zero-extended to a word in final machine code.
3. The 'qword' in 'push dword imm' direct the NASM use the Form 3,
no matter how long the imm given in the instruction it is, the imm
was trucked or zero-extended to a dword in final machine code.
Note: the 'qword' in the instruction but 'dword' in final machine
code, which made us confused.
4. if none of 'byte', 'word', 'qword' is given, the NASM use the From 3.
请参见以下示例:
# cat -n push.asm
1 bits 64
2
3 push byte 0x21
4 push byte 0x4321
5
6 push word 0x4321
7 push word 0x654321
8
9 push qword 0x654321
10
11 push 0x21
12 push 0x4321
13 push 0x654321
14 push 0x87654321
15 push 0xa987654321
16
# nasm -v
NASM version 2.04rc1 compiled on Feb 21 2009
# nasm push.asm -o push.bin
push.asm:4: warning: signed byte value exceeds bounds
push.asm:7: warning: word data exceeds bounds
# ndisasm -b 32 push.bin // 'ndisasm -b 64 push.bin' not works right in this version of NASM.
00000000 6A21 push byte +0x21
00000002 6A21 push byte +0x21
00000004 66682143 push word 0x4321
00000008 66682143 push word 0x4321
0000000C 6821436500 push dword 0x654321
00000011 6821000000 push dword 0x21
00000016 6821430000 push dword 0x4321
0000001B 6821436500 push dword 0x654321
00000020 6821436587 push dword 0x87654321
00000025 6821436587 push dword 0x87654321
In newer NASM, the behavior changes:
(1) 'push 0x21' was encoded to '6A21' in NASM 2.10.01,
while '6821000000' in NASM 2.04rc1;
(2)'push dword 0x654321' in 64 bit mode was allowed
in NASM 2.10.01 and encoded to '6821436500'
最佳答案
手册有误。 (顺便说一下,这不是唯一的错误)
在64位模式下,没有32位推送。 push
是少数几个没有REX.W前缀而提升为64位的指令之一,您无法将其降级。
编辑:实际上,我的手册版本说的很对:
推动符号扩展的imm32。
堆栈指针为
随尺寸减小
堆栈指针。
因此,在64位模式下,翻译为“按下qword,从立即数扩展符号”。