2

In Intel 32 bit architecture, I can have a call with 32 bit address location using the ModR/M byte. According to Intel Manual, I need to have /2 (010B) for opcode extension, 00B for Mod and 101B allows me to have 32 bit displacement.

If I want to have a far call in 64 bit architecture such that I would have room for 64 bit address, I know I can /3 (011B) for opcode extension. However, still 32 bit displacement is only provided. Is there any way of specifying the target as 64 bit address?

Mainly, I would like to know how can I have a call given the 64 bit address of the location.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
masec
  • 584
  • 5
  • 16
  • 1
    Read Intel's manual: https://www.felixcloutier.com/x86/CALL.html. `call far m16:64`. And BTW, the target of a far call is a seg:offset, so it's 80 (64+16) or 48 (32+16) bits, not 64. – Peter Cordes Feb 09 '19 at 20:17
  • Thanks for the link. I do not understand how to use the segment selector. Would you help me more with that? Can you give me the opcode except the address part? Like can you give me a reference of how to assemble the seg, offset and the opcode? – masec Feb 09 '19 at 20:22

1 Answers1

3

Are you asking if call far [64_bit_absolute] is encodable? To fetch the m16:64 80-bit operand from a 64-bit absolute address?

No, call far [mem] isn't special, and ModRM can only do [disp32] or [RIP+rel32], or addressing modes involving registers. Referencing the contents of a memory location. (x86 addressing modes)

Only mov al/ax/eax/rax, [abs64] is encodable with a 64-bit absolute address, using a special form of moffs MOV that doesn't use a ModRM byte. This is useless for you: having the segment or offset in a register doesn't help you.

But you can use mov r64, imm64 to put the address in a register. e.g.

mov  rax, absolute_address      ; where seg:off are stored
call far [rax]

Or if your static address is 64-bit, but your assembler + linker know it's in range of the call instruction, call far [rel seg_and_offset] can use a RIP-relative addressing mode.


Otherwise, maybe you're confusing the seg:off call target with location it's stored? In 64-bit mode, call ptr16:64 (direct far call) isn't available, so you always need the seg:off in memory for call to fetch. But it can be on the stack or whatever, e.g.

push 0x23        ; new CS value ends up in the low 2 bytes of a qword
push rax         ; new offset.  It goes at a lower address because x86 is little-endian
call far [rsp]
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847