Question

I'm writing on a very basic kernel. I tried to write a function, with parameters passed through the stack. The kernel is compiled with nasm (like described in this question) and run with QEMU. I'm using gdb for debugging.

After a long while having problems I wrote this to test some basic stack operations:

BITS 16

global start
start:
    mov ax, 0x7C00
    add ax, 288
    mov ss, ax
    mov sp, 4096
    mov ax, 0x7C00
    mov ds, ax

test:
    push 42
    push 43
    push "T"
    pop ax
    pop ax
    push 44
    pop ax
    pop ax
    jmp $

Going through this step by step and looking what sp contains and looking what at the pointed address is reveals that sp is de-/incremented right, but the address it's pointing to always contains 0x0000.

I thought this could be related to the mov sp, 4096 line. So I commented it out. This didn't work either. The only difference was that the values sp points to are now some others but not the ones I pushed there.

Is there something I have to do to initialize the stack or something similar?

Was it helpful?

Solution

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 to 0x7C00 + 288 and SP to 4096. Thus the physical stack pointer address is ((0x7c00+0x0120)<<4) + 0x1000 giving 0x7e200.
  • 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 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top