86和x86-64机code的差异 [英] Differences of x86 and x86-64 machine code

查看:269
本文介绍了86和x86-64机code的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有产生JIT x86机器code和直接执行它的程序,我希望它支持X86-64 / AMD64 / 64为好。最明显的区别是:

So, I've got a program which generates JIT x86 machine code and executes it directly and I want it to support x86-64/AMD64/x64 as well. The obvious differences are:


  • 新寄存器( RAX R8 ...)和指针宽度(指针需要使用64位暂存器)

  • 默认C调用约定(堆栈与寄存器参数)

  • 一些新的助记符( pushq 推64位)

  • New registers (rax, r8...) and pointer width (pointers need to use 64bit regs)
  • Default C calling convention (arguments on stack vs. registers)
  • Some new mnemonics (pushq to push 64bit)

是否有在二进制指令的任何差异,以及或者它应该是(大约)足够用 pushq 和64位寄存器,在适当的时候和code将只工作?

Are there any differences in the binary instructions as well or should it be (roughly) sufficient to use pushq and 64bit registers when appropriate and the code will just work?

code例如:

static inline void emit_call(uint32_t target) {
    emit_byte(0xE8);
    emit_dword(target - ((uint32_t)out + 4));
}

如果我用 uintptr_t形式而不是 uint32_t的我认为这仍然正常工作,
但可以加载立即到64位的寄存器 RAX 是加载到较低的32位别名不同:

This would still work if I use uintptr_t instead of uint32_t I assume, but loading an immediate into a 64bit register rax is different from loading it into the lower 32bit alias:

static void emit_mov_x86reg_immediate(int x86reg, int imm) {
    emit_byte(0xB8 | x86reg);
    emit_dword(imm);
}

还有没有其他的区别?

Are there any other differences?

在code我的工作是可访问的这里,如果你想看看吧。

The code I'm working on is accessible here, if you want to take a look at it.

推荐答案

有实际上老的32位推和新的64位推没有什么区别,这是的是的的几个指令之一含蓄的64位。

There's actually no difference between the old 32bit push and the new 64bit push, that's one of the few instructions that are implicitly 64bit.

相对分支和调用仍然使用32位的偏移量。

Relative branches and calls still use 32bit offsets.

一些实际的差别是:


  • 的REX preFIX,显然,额外的寄存器(也记得 SIL DIL - 一个REX preFIX有没有设置仍可重要的位!)

  • 再次REX preFIX,它使用的是短编码( 40 + RD 48 + RD )的 INC 。因此, INC 十二月必须在 FF / 1 编码。

  • 裂口 -relative解决

  • 64位负载直接和 MOV 有直接64位地址

  • 符号扩展32位到64位( movsxd )的股票操作code与 ARPL

  • LES LDS 不存在,重用为VEX prefixes(以32位模式下,只有 LES LDS 非法操作数是VEX prefixes,这就是为什么VEX prefixes的编码有点奇怪)

  • 没有人使用,或在64位模式无用被删除
  • 几个老指令(十进制数学,约束 PUSHAD 流行ES 和朋友)

  • 82 /? 的别名80 /?不再有效

  • LAHF SAHF 不要在一些老的x64处理器存在(不是说你无论如何使用它们..)

  • the REX prefix, obviously, for extra registers (also remember sil and dil - a REX prefix with none of the bits set can still matter!)
  • the REX prefix again, it used to be the short encoding (40+rd, 48+rd) for inc and dec. So inc and dec must the FF /1 encoding.
  • rip-relative addressing
  • 64bit load immediate and mov with a direct 64bit address
  • sign-extend 32bit to 64bit (movsxd) shares opcode with arpl
  • les and lds don't exist, reused as VEX prefixes (in 32bit mode, only les and lds with illegal operands are VEX prefixes, which is why the encoding of VEX prefixes is a bit odd)
  • several old instructions that no one was using or are useless in 64bit mode were removed (decimal math, bound, into, pushad, pop es and friends)
  • the 82 /? aliases of 80 /? are no longer valid
  • lahf and sahf don't exist on some old x64 processors (not that you'd use them anyway..)

这篇关于86和x86-64机code的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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