EerieNight
EerieNight

Reputation: 51

IA32 Assembly far calls and segment offset size

i'm new about Assembly. A couple of days ago i read about memory segmentation/paging in IA32 architecture, and now i'm studying Assembly far calls.

Ok, with the IA32 segmentation there is a 16-bit segment register, and a 32-bit segment offset. Together, they form the logical address/far pointer (segmentation with paging), or the linear address (segmentation without paging). Regarding far calls, i'm now reading that the segment register (CS) and the 16 bit offset are PUSHed before the jump.

The questions: why is this offset 16 bit long? Is it an internal selector for the segment, rather than an offset for calculating the linear/logic address?

Does the operational mode matter with far calls?

Thanks in advice.

Upvotes: 1

Views: 1416

Answers (2)

markgz
markgz

Reputation: 6266

"Regarding far calls, i'm now reading that the segment register (CS) and the 16 bit offset are PUSHed before the jump."

That is not correct: The 16 bit segment register and the 32 bit offset are pushed onto the stack if the current CS segment descriptor specifies a 32 bit segment. If the current CS segment descriptor specifies a 16 bit segment then the offset is 16 bits.

From the Intel® 64 and IA-32 Architectures Software Developer’s Manual

3.3.5 32-Bit and 16-Bit Address and Operand Sizes

When using 32-bit addressing, a logical address (or far pointer) consists of a 16-bit segment selector and a 32-bit offset ... the segment descriptor for the currently executing code segment defines the default address and operand size.

7.3.15.2 Far Control Transfer Instructions

The JMP and CALL instructions (see Section 7.3.8, “Control Transfer Instructions”) both accept a far pointer as a source operand to transfer program control to a segment other than the segment currently being pointed to by the CS register. When a far call is made with the CALL instruction, the current values of the EIP and CS registers are both pushed on the stack.

Upvotes: 1

zwol
zwol

Reputation: 140445

You should start by programming to the ELF or Windows 32-bit flat user space model, in which:

  • All of the RAM available to your process is mapped into a 4GB (232-byte) linear address space. (Not all of that address space is necessarily usable by your program, and you must use operating system / C library interfaces, e.g. malloc, to get more of it than you start with.) Memory is allocated in pages, which are 4096 bytes each (with rare exceptions) which may be any combination of readable, writable, and executable; a 32-bit pointer can point to any byte on any page.
  • There is only one kind of absolute call instruction and it can reach any address.
  • For all practical purposes, segments and the segment registers do not exist.1
  • There are eight integer registers (%eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, and %esp) all of which are 32 bits wide and can hold an address. %esp is reserved for use as the stack pointer, the others can be used for anything you like; but you should read up on the C calling convention defined by your operating system, so you know which registers are call-clobbered and which are call-saved (it's different for Windows and non-Windows, so I can't just tell you).

You can also, if you like, start with the 64-bit flat user space model; the important differences are that there are now sixteen integer registers, they're all 64 bits wide, the calling convention is more complicated, and your RAM is now mapped into a 248-byte linear address space.

Only after you have fully mastered the capabilities of the CPU in this mode should you even think about learning either protected-mode kernel programming (in which you do have to know about segments and the segment registers, but only as a detail of how virtual memory works) or 16-bit programming (in which the segments are actually important). Personally I wouldn't bother with 16-bit mode; the only thing it's used for anymore is just barely enough bootloader code to get out of 16-bit mode.

1 The C library and OS may play clever tricks to make use of %fs and/or %gs as additional pointers with very specific functions, but they cannot be used for anything you like. %cs, %ds, %es, and %ss can't be used at all in the flat user space model (more precisely, setting up the flat model requires them to be set to fixed values and then never changed again).

Upvotes: 3

Related Questions