我正在写一个非常基本的内核。我试着编写一个函数,参数通过堆栈传递。内核使用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
指的是现在的其他值,但不是我推到那里的值。
我是否需要做一些事情来初始化堆栈或类似的东西?
答案 0 :(得分:1)
16*$ss + $esp
。 (就像杰斯特在评论中所说的那样)DS
寄存器。SS
设置为0x7C00 + 288
并将SP
设置为4096.因此,物理堆栈指针地址为((0x7c00+0x0120)<<4) + 0x1000
,提供0x7e200
。<强> 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