Search code examples
x86-16microprocessorsreal-modememory-segmentation

Generating address of a instruction using Code Segment and Instruction Pointer


Consider the Code Segment Address to be FE00 and Instruction Pointer to be ABBE. Shifting the Code Segment by 4 bits and Adding the Instruction pointer leads to an additional carry. How do we represent the generated address?


Solution

  • Consider the Code Segment Address to be FE00 and Instruction Pointer to be ABBE. How do we represent the generated address?

    Either you represent the address as

    • 0FE00h:0ABBEh, its segmented form using two 16-bit numbers separated by a colon and always (segment - colon - offset)
    • 00108BBEh, its linear form using one 32-bit number

    No matter your choice it will always require 2 word sized registers on 8086.

    "The instruction pointer is an offset in the 64KB memory segment that starts at the linear address obtained from multiplying the value in the CS code segment register by 16 (same as shifting left 4 times)."

    Calculating the linear address could be done inefficiently (but easy to understand) like this:

    mov     ax, 0FE00h  ; The code segment
    mov     dx, 16
    mul     dx          ; "shifting the code segment by 4 bits"
    add     ax, 0ABBEh  ; "adding the instruction pointer"
    adc     dx, 0       ; Taking care of the additional carry
    

    This linear address 00108BBEh uses 2 registers AX and DX. The AX register will hold the least significant part 8BBEh and the DX register will hold the most significant part 0010h. If you need to refer to the whole pair of registers you do it like DX:AX. So highWord - colon - lowWord.

    Unlike with seg:off notation, this is just one 32-bit number split over 2 registers, no overlapping place values. The low bit of the high half has place value 2^16 when we're talking about a flat 32-bit (or 20-bit) number, not a seg:off address.