%sp寄存器不指向堆栈

时间:2014-03-12 13:37:01

标签: assembly gdb stack qemu osdev

我正在写一个非常基本的内核。我试着编写一个函数,参数通过堆栈传递。内核使用nasm编译(如this question中所述)并与QEMU一起运行。我正在使用gdb进行调试。

经过一段时间的问题,我写了这个来测试一些基本的堆栈操作:

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 $

逐步完成并查看sp包含的内容,并查看指向的地址是什么,显示sp向右递增,但它指向的地址始终包含0x0000。

我认为这可能与mov sp, 4096行有关。所以我评论了它。这也不起作用。唯一的区别是值sp指的是现在的其他值,但不是我推到那里的值。

我是否需要做一些事情来初始化堆栈或类似的东西?

1 个答案:

答案 0 :(得分:1)

说明

  • 您想在GDB中查看16*$ss + $esp。 (就像杰斯特在评论中所说的那样)
  • 这在x86 Segmentation中有解释。请注意,这同样适用于数据存储器访问和DS寄存器。
  • 您将SS设置为0x7C00 + 288并将SP设置为4096.因此,物理堆栈指针地址为((0x7c00+0x0120)<<4) + 0x1000,提供0x7e200
  • 以十六进制编写代码中的所有内存地址和偏移量可能有助于算术运算。

编写GDB以检查堆栈

<强> 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

<强>检查-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 */
    }
}

构建:

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

示例会话

$ 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