我使用NASM和qemu玩真实模式裸机编程。我试图理解堆栈是如何工作的,特别是它是如何存储在内存中的。
我的代码位于一个512字节的引导扇区中,带有"魔术字节"最后0xaa55
,它在内存地址0x7c00
加载。
我已将堆栈基指针设置为0x7cfe
。我知道我必须注意不要用堆栈覆盖我的代码,但事实并非如此。我的代码只占用几个字节。这是我的代码:
[BITS 16]
org 0x7c00
mov bp, 0x7cfe
mov sp, bp
push 'A'
jmp $
times 510-($-$$) db 0
dw 0xaa55
程序设置堆栈指针,推送字符“A'进入堆栈,然后启动和无限循环。我使用以下命令汇编并调整它:
nasm -f bin boot.asm -o boot.bin
&& qemu-system-i386 -drive file=boot.bin,index=0,media=disk,format=raw -monitor stdio
当模拟器正在运行时,我按以下方式转储内存:
qemu> pmemsave 0x7c00 512 medump.bin
当我打开文件memdump.bin
时,我会看到字符' A' (41 00
因为是小端)在基地址和之前(如果我们考虑堆栈的话,在顶部)我看到很多"垃圾",即:
200: 00 00 00 00 C5 EF 00 00 00 00 00 00 02 02 00 DF 00 00 FE F7
220: 00 00 FE 7C 00 00 BC 93 00 00 00 DF 00 00 60 F8 00 00 00 00
240: 00 00 55 AA 00 00 08 7C 00 00 02 02 41 00 00 00 00 00 00 00
那些字节是什么?
如果我没有设置堆栈指针,那么代码之后和字节0xaa55
之前的所有字节都是零。
您能提供任何信息或至少提供一些指示吗?
由于
答案 0 :(得分:3)
为了处理中断,CPU需要正确设置堆栈
仅通过将控制传递给ISR(中断服务路由)来提供中断,CPU就会推送FLAGS
,CS
和IP
。
然后,ISR可能并且通常需要更多堆栈。
堆栈背后的基本假设是 SS:SP
以下的所有内容都被认为是免费的,可用的内存。
当您将SP
设置为 7cfeh 时,您只是说 7cfeh 下面的每个内存位置都可以被其他人用作堆栈内存。
这就是你看到的垃圾
请注意,列出为 200 , 220 和 240 的地址在堆栈指针下面,在我看来使用& #34;在顶部"对于这样的地址,虽然比喻正确,但有点令人困惑。
如果你想确保成为唯一一个弄乱堆栈的人,请尽早发出cli
(绝对在设置堆栈之前)。
这在UP系统中就足够了。
修改的
不要假设SS
为零,明确设置,用
mov ax, <ss_value>
;cli Decomment for very old 8088 compatibility
;Use these instructions in this order in pair
;Interrupts are disabled for 1 inst after mov ss, ...
mov ss, ax
mov sp, <sp_value>
;sti Decomment for very old 8088 compatibility