What is the meaning of x86 instruction "call dword ptr ds:[00923030h]"?

Marek picture Marek · Feb 5, 2009 · Viewed 10.6k times · Source

What does the following x86 assembler instruction do?

call dword ptr ds:[00923030h]

It's an indirect call I suspect, but exactly how does it compute the address to the call?

Answer

Adam Rosenfield picture Adam Rosenfield · Feb 5, 2009

[EDIT] Updated

Whenever you see a memory operand that looks something like ds:0x00923030, that's a segment-relative addressing mode. The actual address being referred tp is at linear address 0x00923030 relative to the base address of the ds segment register.

Memory segmentation in the x86 architecture is somewhat confusing, and I think Wikipedia does a good job of explaining it.

Basically, x86 has a number of special segment registers: cs (code segment), ds (data segment), es, fs, gs, and ss (stack segment). Every memory access is associated with a certain segment register. Normally, you don't specify the segment register, and depending on how the memory is accessed, a default segment register is used. For example, the cs register is used for reading instructions.

Each segment register has a certain base address and a limit. The base address determines the physical address that linear address 0x00000000 corresponds to, and the limit determines the maximum allowable linear address for that segment. For example, if the base address were 0x00040000 and the limit was 0x0000FFFF, then the only valid linear addresses would be 0x00000000 to 0x0000FFFF, and the corresponding physical addresses would be 0x00040000 to 0x0004FFFF.

Thus, the physical address at which the subroutine being called resides is given by the base address stored in the ds segment register, plus 0x00923030. But we're not done yet -- the instruction has the word ptr in it. This adds an extra level of indirection, so the actual target of the subroutine is the address stored at the location ds:0x00923030.

In AT&T syntax (accepted by the GNU assembler), the instruction would be written as follows:

lcall *ds:0x00923030

For the full gory details of what the instruction does, see the 80386 reference manual. This particular variant of the instruction is "CALL r/m16" (call near register indirect/memory indirect).