4
votes

The first form of JMP in x86-64 is:

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

So for example JMP rel8=-2 is eb fe. fe is a one byte signed 2s-compliment -2.

How do I express this rel8 immediate in Intel syntax?

I tried the following:

test.s:

.intel_syntax noprefix
.global _start
_start:
    jmp -2

Compile with:

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

But I get:

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

Not eb fe as desired.

(More generally, where is Intel syntax documented? I couldn't find anything in the Intel manual about it. The Intel manual explains how to encode operands, but it doesn't give the syntax of the assembly language.)

Update:

Solution is:

.intel_syntax noprefix
.global _start
_start:
    jmp .

. must represent address of current instruction. Assembling it and disassembling gives:

4000d4: eb fe      jmp    4000d4 <_start>

eb fe as desired. RIP-relative addressing is in terms of the next instruction, so the assembler must adjust for the size of the current instruction for you.

1
Have you tried jmp $+offset? Or jmp $ in this caseharold
@harold: Error: junk '$-2' after expression and Error: junk '$' after expression respectively.Andrew Tomazos
Ok, how about jmp . + offset? Apparently GAS breaks with tradition again..harold
@harold: See update. Thanks.Andrew Tomazos
Good question about Intel syntax not being documented. The problem is that it isn't even standardized, so different assemblers have to document their own syntax (even though they're usually highly similar). NASM and YASM docs for example seem to assume you already know MASM syntax, and just point out the differences from it (like mov reg, sym is mov reg, imm32, not mov reg, [mem]). IIRC, GNU docs for AT&T syntax is not bad, since gas is the only major assembler that uses it. I've had to go looking to check the NASM syntax for register-indirect jmp rax, and it's hard to find.Peter Cordes

1 Answers

4
votes

(G)AS apparently uses . to denote the current address (the address of the current instruction), unlike most other assemblers.

There is a tiny page documenting it here in the documentation.