64bit mode: Absolute JMP encoding

2008-12-17
2013-06-04
  • Hello,

    What is the syntax for a 64-bit absolute jump in NASM?

    For instance what I want to do is this:
    [BITS 64]
    jmp 0x1234567890ABCDEF

    According to the Intel manuals this should be encoded with opcode 0xFF (followed by a 64-bit address) but NASM keeps using opcode 0xE9 (with a 32-bit offset address).

    How can I get NASM to encode a 64-bit absolute jump?

    Thanks,
    -Ian

     
    • Nathan
      Nathan
      2008-12-18

      I think you might need to twiddle the DEFAULT directive.  Read about it here:

      http://www.nasm.us/doc/nasmdoc6.html#section-6.2

      My conclusion from early experiments (using version 2.06rc1) is that 'DEFAULT REL' is active unless an alternative is specified.  The docs seem to have a different opinion.

      Nathan.

       
    • Looking at the NASM source code by default it is set to use absolute address.

      globalrel is set to 0 in nasm.c
      setting DEFAULT REL sets globalrel to 1 and DEFAULT ABS sets globalrel to 0

      So the source code reads that ABS is the default way (So the docs are correct).

      Using either the REL or ABS options don't make any difference that I can see in the binary it generates.

      With this as my source:
      [BITS 64]
      [ORG 0x0000000000100000]

      kernel_start:

          jmp start

      The binary shows up as (JMP rel32 as per the Intel docs where RIP = RIP + 32-bit displacement):
      0xE9 0xDB 0x00 0x00 0x00

      What I am expecting is something like this (JMP r/m64 as per the Intel docs where RIP = 64-bit offset from register or memory):
      0xFF 0x?? 0xDB 0x00 0x00 0x00 0x00 0x00 0x00 0x00 (or something like that.. a full 64-bit address)

      -Ian

       
    • Oh!  I've been talking about linker output.  You are looking at the '-f bin' format which probably, until now, has not been tested by anyone.

       
    • Heh.. it's always something. Yes, I am using binary format. The reason is that I am using NASM to develop an Operating System.

      Link is here is anyone is interested: http://www.returninfinity.com/bare-metal-os

      The JMP's are working as is but if I move calls more that 4GB's away from each other I will run into some problems I think.

      Any of the developers have any ideas on this?

      Thanks,
      -Ian

       
    • There is no such instruction. You have to do:

      mov rax, qword 0x1234567890ABCDEF
      jmp rax

      Agner