问题
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?
回答1:
Explanation
- You want to look at
16*$ss + $espin GDB. (Like Jester suggested in his comment) - This is explained in x86 Segmentation. Note the same applies to data memory access and the
DSregister. - You set
SSto0x7C00 + 288andSPto 4096. Thus the physical stack pointer address is((0x7c00+0x0120)<<4) + 0x1000giving0x7e200. - 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
来源:https://stackoverflow.com/questions/22353268/sp-register-doesnt-point-to-stack