看到这个7C00h的值,你可能正在开发一个引导程序。
并且你想要让堆栈位于引导程序
下方。
你需要做出的一个重要选择是如何处理启动时生效的分段寻址方案。
ORG 7C00h
这表示代码的第一个字节将在偏移量7C00h处。为了使其正常工作,您必须将段寄存器初始化为0000h。请记住,BIOS以线性地址00007C00h加载了引导程序,相当于段:偏移对0000h:7C00h。
如果您要更改
SP
寄存器,则同时更改
SS
段寄存器。您不知道代码开始时这些寄存器包含什么,并且应该(大多数情况下)总是同时修改这些寄存器。首先分配
SS
,然后直接分配
SP
。对
SS
的
mov
或
pop
在此和以下指令之间阻止了许多种类型的中断,因此您可以安全地设置一致的(2个寄存器的)堆栈指针。
mov ss, ax
mov bp, ax <== This ignored the above safeguard!
mov sp, bp
ORG 7C00h
mov bp, 7C00h
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, bp
push 'A'
mov bx, 0007h
mov al, [7BFEh]
mov ah, 0Eh
int 10h
作为替代方案,因为你已经设置了
BP=7C00h
,你可以通过以下方式读取堆栈中的字符:
mov al, [bp-2]
。
ORG 0000h
这表示代码的第一个字节将位于偏移量0000h处。为了使其正常工作,您需要将某些段寄存器初始化为07C0h。请记住,BIOS将引导加载程序加载到线性地址00007C00h,这相当于段:偏移对07C0h:0000h。
由于堆栈必须位于引导加载程序下面,所以SS
段寄存器将与其他段寄存器不同!
ORG 0000h
mov bp, 7C00h
mov ax, 07C0h
mov ds, ax
mov es, ax
xor ax, ax
mov ss, ax
mov sp, bp
push 'A'
mov bx, 0007h
mov al, [bp-2]
mov ah, 0Eh
int 10h
ORG 0200h
这里提到线性地址有多种转换为段:偏移量。
ORG 0200h
表示代码的第一字节将位于 offset 0200h 处。要使其正常工作,您需要将段寄存器初始化为 07A0h。请记住,BIOS 将引导加载程序加载到线性地址 00007C00h,这相当于段:偏移量对 07A0h:0200h。
由于 512 字节的堆栈位于引导加载程序 下面,所以 SS
段寄存器将再次与其他段寄存器相等!
ORG 0200h
mov bp, 0200h
mov ax, 07A0h
mov ds, ax
mov es, ax
mov ss, ax
mov sp, bp
push 'A'
mov bx, 0007h
mov al, [bp-2]
mov ah, 0Eh
int 10h
你还可以通过mov al, [01FEh]
来提取字符。
mov al, SS:[7BFEh]
访问堆栈值,因为处理器隐式执行mov al, DS:[7BFEh]
,所以您需要进行SS覆盖。 - Michael Petch