如何“推IMM恩codeS? [英] How 'push imm' encodes?

查看:268
本文介绍了如何“推IMM恩codeS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的<&下;英特尔64和IA-32架构软件开发人员手册卷2B:指令集参考,N-Z >>说:

  |欧普code * |指南| OP / EN | 64位模式| COMPAT /腿模式|说明|
| 6A | PUSH的imm8 | B |有效|有效|按imm8指定。 |
| 68 | PUSH imm16 | B |有效|有效|推imm16。 |
| 68 | PUSH imm32 | B |有效|有效|推imm32。 |

#猫-n TEST.ASM

  1位64
 2
 3推12个字节
 4推12字
 5推双字12
 6推四字12
 7

#NASM TEST.ASM

  TEST.ASM:5:错误:指令64位模式下不支持


  1. 为什么第5行是非法的?我认为它匹配'PUSH imm32。


  2. 为什么6号线是合法的吗?它不匹配任何'PUSH的imm8 / PUSH imm16 / PUSH imm32的。


请帮助我!

== ==测试

 我认为英特尔手册是正确的,而推IMM
    指令执行有三种编码格式:
    表1:6A XX
    表2:66 68 XX XX
    表格3:68 XX XX XX XX    我们现在争论的是NASM法实施具体行为。    在NASM 2.04rc1(上面的例子中我给出):
    1.在推字节IMM的字节直接NASM使用Form 1,
       无论是在指令它是,IMM给出的IMM多久
       集群是在最终的机器code一个字节。
    2.在推字IMM'的'字'直接NASM使用Form 2,
       无论是在指令它是,IMM给出的IMM多久
       被卡车或零扩展到最终的机器code字。
    3.在推DWORD IMM的四字直接NASM使用Form 3,
       无论是在指令它是,IMM给出的IMM多久
       被卡车或零扩展到最终的机器code双字。
       注:在最后机器指令中的四字,而是DWORD
       code,这使我们感到困惑。
    4.如果没有字节,字,四字的已定,那么NASM使用从3。

请参阅下面的例子:

 #猫-n push.asm
1位64
2
3推字节为0x21
4推字节0x4321

6推字0x4321
7推字0x654321
8
9推四字0x654321
10
11推为0x21
12推0x4321
13推0x654321
14推0×87654321
15推0xa987654321
16
#NASM -v
NASM版本2.04rc1于2009年2月21日编译
#NASM push.asm -o push.bin
push.asm:4:警告:​​符号字节值超过界限
push.asm:7:警告:字数据超出界限
#ndisasm -b 32 push.bin //'ndisasm -b 64 push.bin的权利在这个版本NASM不工作。
00000000 6A21推字节+ 0×21
00000002 6A21推字节+ 0×21
00000004 66682143推字0x4321
00000008 66682143推字0x4321
0000000C 6821436500推DWORD 0x654321
00000011 68.21亿推DWORD为0x21
00000016 6821430000推DWORD 0x4321
0000001B 6821436500推DWORD 0x654321
00000020 6821436587推DWORD 0×87654321
00000025 6821436587推DWORD 0×87654321在较新的NASM,更改的行为:
(1)推为0x21是连接在NASM 01年2月10日coded到'6A21',
    而在NASM 2.04rc168.21亿;
(2)推DWORD 0x654321在64位模式被允许
    在NASM零一年二月十日和连接coded到'6821436500'


解决方案

本手册是错误的。 (这不是唯一的错误,顺便说一句)

在64位模式,不存在32位推。 是被提拔没有REX.W preFIX到64位的几个指令之一,你不能降级了。

编辑:其实,我的手动版本说正确的事:


  

按符号扩展imm32。
  堆栈指针
  通过的尺寸递减
  堆栈指针。


因此​​,在64位模式下,翻译过来就是推四字,符号从眼前延伸。

The << Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2B: Instruction Set Reference, N-Z >> says:

| 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

  1. Why the line 5 is illegal? I think it matches 'PUSH imm32'.

  2. And why the line 6 is legal? It does not match any of 'PUSH imm8/PUSH imm16/PUSH imm32'.

Help me, please!

======Test======

    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.

See the following example:

# 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'

解决方案

The manual is wrong. (this is not the only error, by the way)

In 64bit mode, there is no 32bit push. push is one of the few instructions that is promoted to 64bit without a REX.W prefix, and you can't demote it.

edit: actually, my version of the manual says the right thing:

Push sign-extended imm32. Stack pointer is decremented by the size of stack pointer.

So in 64bit mode, that translates to "push a qword, sign extended from the immediate".

这篇关于如何“推IMM恩codeS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆