Explanation
- You want to look at
16*$ss + $esp
in GDB. (Like Jester suggested in his comment) - This is explained in x86 Segmentation. Note the same applies to data memory access and the
DS
register. - You set
SS
to0x7C00 + 288
andSP
to 4096. Thus the physical stack pointer address is((0x7c00+0x0120)<<4) + 0x1000
giving0x7e200
. - Writing all memory addresses and offsets in your code in hexadecimal may help with the arithmetic.
Scripting GDB to Examine the Stack
boot.asm
BITS 16 global start start: mov ax, 0x7C00 add ax, 0x0120 mov ss, ax mov sp, 0x1000 mov ax, 0x7C00 mov ds, ax test: push 42 push 43 push 'T' pop ax pop ax push 44 pop ax pop ax hlt
examine-stack.gdb
set confirm 0
set pagination 0
set architecture i8086
target remote localhost:1234
file boot
set disassemble-next-line 1
define hook-stop
printf "Stack Pointer: 0x%04x, AX: 0x%04x\n", ($ss*16 + $esp), $ax
# after stack setup, the linear stack pointer address is 0x7e200
set variable $sp_linear = 0x7e200
x/8xb ($sp_linear - 8)
end
break test
continue
set variable $i = 0
while $i < 8
stepi
set variable $i = $i + 1
end
monitor quit
disconnect
quit
x86-boot.ld
ENTRY(start); SECTIONS { . = 0x7C00; .text : AT(0x7C00) { _text = .; *(.text); _text_end = .; } .data : { _data = .; *(.bss); *(.bss*); *(.data); *(.rodata*); *(COMMON) _data_end = .; } .sig : AT(0x7DFE) { SHORT(0xaa55); } /DISCARD/ : { *(.note*); *(.iplt*); *(.igot*); *(.rel*); *(.comment); /* add any unwanted sections spewed out by your version of gcc and flags here */ } }
Build with:
nasm -g -f elf -F dwarf boot.asm -o boot.o cc -nostdlib -m32 -T x86-boot.ld -Os -Wall -g3 -I. -Wl,--build-id=none boot.o -o boot objcopy -O binary boot boot.good.bin
Sample Session
$ qemu-system-x86_64 -s -S boot.good.bin & $ gdb -q -x examine-stack.gdb The target architecture is assumed to be i8086 0x0000fff0 in ?? () Breakpoint 1 at 0x7c10: file boot.asm, line 13. Stack Pointer: 0x7e200, AX: 0x7c00 0x7e1f8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Breakpoint 1, test () at boot.asm:13 13 push 42 => 0x00007c10 : 6a 2a push $0x2a Stack Pointer: 0x7e1fe, AX: 0x7c00 0x7e1f8: 0x00 0x00 0x00 0x00 0x00 0x00 0x2a 0x00 14 push 43 => 0x00007c12 : 6a 2b push $0x2b Stack Pointer: 0x7e1fc, AX: 0x7c00 0x7e1f8: 0x00 0x00 0x00 0x00 0x2b 0x00 0x2a 0x00 15 push 'T' => 0x00007c14 : 6a 54 push $0x54 Stack Pointer: 0x7e1fa, AX: 0x7c00 0x7e1f8: 0x00 0x00 0x54 0x00 0x2b 0x00 0x2a 0x00 16 pop ax => 0x00007c16 : 58 pop %ax Stack Pointer: 0x7e1fc, AX: 0x0054 0x7e1f8: 0x00 0x00 0x54 0x00 0x2b 0x00 0x2a 0x00 17 pop ax => 0x00007c17 : 58 pop %ax Stack Pointer: 0x7e1fe, AX: 0x002b 0x7e1f8: 0x00 0x00 0x54 0x00 0x2b 0x00 0x2a 0x00 18 push 44 => 0x00007c18 : 6a 2c push $0x2c Stack Pointer: 0x7e1fc, AX: 0x002b 0x7e1f8: 0x00 0x00 0x54 0x00 0x2c 0x00 0x2a 0x00 19 pop ax => 0x00007c1a : 58 pop %ax Stack Pointer: 0x7e1fe, AX: 0x002c 0x7e1f8: 0x00 0x00 0x54 0x00 0x2c 0x00 0x2a 0x00 20 pop ax => 0x00007c1b : 58 pop %ax Stack Pointer: 0x7e200, AX: 0x002a 0x7e1f8: 0x00 0x00 0x54 0x00 0x2c 0x00 0x2a 0x00 21 hlt => 0x00007c1c : f4 hlt