rel8 立即操作数的 x86-64 英特尔语法?

Posted

技术标签:

【中文标题】rel8 立即操作数的 x86-64 英特尔语法?【英文标题】:x86-64 Intel Syntax for rel8 immediate operand? 【发布时间】:2013-11-03 09:56:59 【问题描述】:

x86-64 中 JMP 的第一种形式是:

Opcode    Instruction  Description
EB cb     JMP rel8     Jump short, RIP = RIP + 8-bit displacement sign

所以例如JMP rel8=-2eb fefe 是一个单字节有符号的 2s-compliment -2。

如何在 Intel 语法中表达这个 rel8 立即数?

我尝试了以下方法:

test.s:

.intel_syntax noprefix
.global _start
_start:
    jmp -2

编译:

$ gcc -nostdlib test.s
$ objdump -d -M intel

但我明白了:

   e9 00 00 00 00           jmp    5 <_start+0x5>

不是eb fe 所希望的。

(更一般地说,英特尔语法记录在哪里?我在英特尔手册中找不到任何关于它的内容。英特尔手册解释了如何编码操作数,但它没有给出汇编语言的语法。)

更新:

解决办法是:

.intel_syntax noprefix
.global _start
_start:
    jmp .

. 必须代表当前指令的地址。组装和拆卸给出:

4000d4: eb fe      jmp    4000d4 <_start>

eb fe 根据需要。 RIP 相对寻址是根据下一条指令进行的,因此汇编器必须为您调整当前指令的大小。

【问题讨论】:

你试过jmp $+offset吗?或者 jmp $ 在这种情况下 @harold: Error: junk '$-2' after expressionError: junk '$' after expression 分别。 好的,jmp . + offset 怎么样?显然 GAS 再次打破传统...... @harold:查看更新。谢谢。 关于英特尔语法没有记录的好问题。问题在于它甚至没有标准化,因此不同的汇编器必须记录自己的语法(即使它们通常高度相似)。例如,NASM 和 YASM 文档似乎假设您已经知道 MASM 语法,并指出与它的区别(例如 mov reg, sym 是 mov reg, imm32,而不是 mov reg, [mem])。 IIRC,AT&T 语法的 GNU 文档还不错,因为 gas 是唯一使用它的主要汇编程序。我不得不去检查注册间接jmp rax 的 NASM 语法,但很难找到。 【参考方案1】:

(G)AS 显然使用. 来表示当前地址(当前指令的地址),这与大多数其他汇编程序不同。

documentation 中有一个小页面记录它。

【讨论】:

以上是关于rel8 立即操作数的 x86-64 英特尔语法?的主要内容,如果未能解决你的问题,请参考以下文章

x86-64 GAS Intel 语法中的 RIP 相对变量引用(如“[RIP + _a]”)如何工作?

x86-64规范地址?

x86-64 C Calling Convention

X86-64 汇编学习1

X86-64 汇编学习1

X86-64 汇编学习1