在16位实模式下堆栈存储器布局

时间:2016-09-23 12:22:29

标签: assembly x86 real-mode

我使用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之前的所有字节都是零。

您能提供任何信息或至少提供一些指示吗?

由于

1 个答案:

答案 0 :(得分:3)

为了处理中断,CPU需要正确设置堆栈 仅通过将控制传递给ISR(中断服务路由)来提供中断,CPU就会推送FLAGSCSIP

然后,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