x86 function call types
Asked Answered
A

1

5

I'm new in x86. My question is about function calls. As far as i know there is three function call types: short call (0xe8), far call (0x9a) and near call (0x??). Some call short call a relative call (ip += arg / cs = inv) and far call an absolute call (ip = arg / cs = arg), but what about near call (ip = ? / cs = ?). Some say that calling function far (9a) is almost certainly wrong on 32-bit systems. Why? Doesn't x86 mean 32-bit system? Is far call's argument a flat address (the one we use in c++ or other languages) or cs:ip notated and how do i convert a plain address into cs:ip form? Is there other function call types?

Adverb answered 28/11, 2013 at 11:7 Comment(3)
x86 is 16, 32 and/or 64 bitEller
Related: Call an absolute pointer in x86 machine codeIndigene
Near duplicate of What is the difference between the encodings for the call instruction in x86 asm?, but I haven't decided which to close as a dup of the other, if at all.Indigene
A
15

The types of CALL instruction are:

  • Near, relative (opcode E8) (call func)
  • Far, absolute (opcode 9A) (call 0x12:0x12345678)
  • Near, absolute, indirect (opcode FF /2) (call [edi])
  • Far, absolute, indirect (opcode FF /3) (call far [edi])

Far call means that it changes the value of the segment selector (cs) in addition to eip. Near call changes only ip/eip/rip.

Relative means that the address will be relative to the address of the next instruction while an absolute call gives the exact address to jump to.

An indirect call specifies the target address in a register or memory contents, while in a direct call it will be specified as part of the instruction.

Some say that calling function far (9a) is almost certainly wrong on 32-bit systems. Why?

Probably because generally 32-bit operating systems will use a flat memory model where all memory can be accessed from the same segment (if access is permitted), so there is no need to change the value of cs.

Far call also pushes CS:EIP instead of just EIP as the return address, which is a problem if you call a normal function that's expecting to find stack args right above the return address.

Doesn't x86 mean 32-bit system?

No. x86 was originally a 16-bit instruction set, and was later extended to 32 bits and then 64 bits. See also Stack Overflow's x86 tag wiki

Is far call's argument a plain address (the one we use in c++ or other languages) or cs:ip notated and how do i convert a plain address into cs:ip form?

I don't know what you mean by a "plain address". On a 32 bit OS with flat memory model the address stored in a C++ pointer will not include a segment selector, so to convert it to a far address you'd add the value of cs.

But for the absolute direct form, you need the right value of cs at built time.

Abyssinia answered 28/11, 2013 at 11:25 Comment(3)
Thanks alot! So i always have to call functions near on 32-bit system. Why there isn't near relative indirect call? What value will have CS on 32-bit systems with flat memory model and if CS is not used on 32-bit systems why it still exists and can i use it to my own purposes?Adverb
Relative indirect call would not make sense. The entire point of an indirect call is to jump to an address that isn't known until runtime, and there is no good way to calculate at link time the distance between that address and the beginning of the next instruction.Arleta
@user2543574 CS will have a selector provided by the OS, that includes the process's entire 4GB address space and allows executing code.Abyssinia

© 2022 - 2024 — McMap. All rights reserved.