Search code examples
assemblyx86bootloaderattreal-mode

Base poiner offset in x86 real mode


Having a following code:

.code16

_entry:
    xorw %ax, %ax   
    movw %ax, %ds
    movw %ax, %ss
    movw %ax, %es
    movw $0x7c00, %ax
    movw %ax, %sp
    movw %ax, %bp

    pushw $49
    callw printh
    addw $4, %sp
lp:
    jmp %cs:lp

printh:
    pushw %bp
    movw %sp, %bp

    movb $0x0e, %ah
    movb 6(%bp), %al
    int $0x10   

    movw %bp, %sp
    popw %bp
    ret

.= _entry + 510
.word 0xaa55 /* little endian will reverse */

by question is in bp offset.

0(%bp) stores the old base pointer (after pushw %bp) 2 bytes

2(%bp) stores the 16-bit return address by call instruction

so value of 49 (ascii char '1') must be at offset 4(%bp), but on practice it is on 6(%bp) offset. Why?

The only logical result is call instructions pushes 4 bytes on stack ???


Solution

  • Answer in a comments.

    The value is actually stored at 4(%bp), but in this case 6(%bp) just happens to be the same, but in general, 6(%bp) would be undefined (some old stack frames data).