【发布时间】: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=-2 是eb fe。 fe 是一个单字节有符号的 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 expression和Error: junk '$' after expression分别。 -
好的,
jmp . + offset怎么样?显然 GAS 再次打破传统...... -
@harold:查看更新。谢谢。
-
关于英特尔语法没有记录的好问题。问题在于它甚至没有标准化,因此不同的汇编器必须记录自己的语法(即使它们通常高度相似)。例如,NASM 和 YASM 文档似乎假设您已经知道 MASM 语法,并指出与它的区别(例如
mov reg, sym是 movreg, imm32,而不是mov reg, [mem])。 IIRC,AT&T 语法的 GNU 文档还不错,因为 gas 是唯一使用它的主要汇编程序。我不得不去检查注册间接jmp rax的 NASM 语法,但很难找到。
标签: assembly x86 x86-64 gnu-assembler intel-syntax