Home > Enterprise >  Why are operands to relative jmp/call instructions treated as absolute by NASM / ndisasm?
Why are operands to relative jmp/call instructions treated as absolute by NASM / ndisasm?

Time:12-29

According to "x86 Instruction Set Reference", EB cb opcode corresponds to JMP rel8 mnemonic which, in turn, corresponds to "Jump short, relative, displacement relative to next instruction." From this, one could conclude (at least I would) that operand of JMP represents an offset relative to IP for both an opcode and mnemonic. The code snippet below proves otherwise:

bits 16
nop
nop
nop
nop
nop
jmp label
label:
   nop

Assembled with nasm -f bin -o test.bin test.asm and then disassembled with ndisasm -b 16 test.bin it produces the following output:

00000000  90                nop
00000001  90                nop
00000002  90                nop
00000003  90                nop
00000004  90                nop
00000005  EB00              jmp short 0x7
00000007  90                nop

The second byte of the EB00 opcode is 0 which is correct and expected as the jump target is the very next instruction (hence offset 0), but the operand of the corresponding jmp mnemonic is 7, which is obviously an absolute address. I could prepend the JMP instruction in the code above with arbitrarily many NOPs (or any other instructions), the effect of which would be such that the opcode of JMP instruction would stay the same, but the operand of its corresponding mnemonic would increase accordingly to adjust to an absolute address of jump target, not a relative one. Is this inconsistency something obvious, expected, intended, common to all assemblers, not only NASM? The behaviour is the same for relative CALL instruction. Is this the way it's supposed to be?

CodePudding user response:

Why are operands to relative jmp/call instructions treated as absolute by NASM / ndisasm?

Machine code is nice for CPUs but inconvenient for humans. In machine code the operands to jmp/call instructions are relative.

Assembly language is nicer for humans (and inconvenient for CPUs). In assembly language the operands to jmp/call instructions are absolute because that's nicer for humans.

Tools (assembler, linker maybe) translate "nicer for humans" into "nicer for CPUs", including converting absolute addresses into relative offsets.

More tools (disassemblers) do the opposite and translate "nicer for CPU" into "nicer for humans", including converting relative offsets into absolute offsets.

  • Related