如何在 x86 实模式下正确设置 SS、BP 和 SP?

The*_* Br 6 x86 assembly callstack bios

我想知道如何正确地做到这一点,因为我这样做的方式行不通。

BP用7C00h设置寄存器,然后用 设置SP寄存器BP,然后推送一些ASCII,然后从内存中获取数据以打印它INT 10h,它工作得很好。

mov ax, 7C00h
mov bp, ax
mov sp, bp

push 'A'

mov ah, 0Eh
mov al, [7BFEh]
int 10h
Run Code Online (Sandbox Code Playgroud)

实际输出是

一种

但是当我这样做时:

mov ax, 7C00h
mov ss, ax
mov bp, ax
mov sp, bp

...
Run Code Online (Sandbox Code Playgroud)

它停止工作。中断被调用,光标移动,但没有打印任何内容。设置SS为 0 也不起作用。请伸出援手。

Sep*_*and 6

查看 7C00h 值,您可能正在处理引导加载程序。
并且您希望堆栈位于引导加载程序下方

您必须做出的一个重要选择是您希望如何处理启动时有效的分段寻址方案。

ORG 7C00h

这表明代码的第一个字节将位于偏移量 7C00h。为了使其正常工作,您必须将段寄存器初始化为 0000h。请记住,引导加载程序由 BIOS 加载到线性地址 00007C00h,相当于段:偏移对 0000h:7C00h。
如果您要更改SP寄存器,那么还要更改SS段寄存器。你不知道它在你的代码的开头包含什么,你应该(大多数)总是一前一后修改这些寄存器。首先分配,SS然后直接分配SP。amov或 a poptoSS阻止了此指令和以下指令之间的多种中断,以便您可以安全地设置一致的(2 寄存器)堆栈指针。

mov ss, ax
mov bp, ax     <== This ignored the above safeguard!
mov sp, bp
Run Code Online (Sandbox Code Playgroud)
ORG  7C00h

mov  bp, 7C00h
xor  ax, ax
mov  ds, ax
mov  es, ax
mov  ss, ax      ; \  Keep these close together
mov  sp, bp      ; / 

push 'A'         ; This writes 0000h:7BFEh

mov  bx, 0007h   ; DisplayPage and GraphicsColor
mov  al, [7BFEh] ; This requires DS=0
mov  ah, 0Eh     ; BIOS.Teletype
int  10h
Run Code Online (Sandbox Code Playgroud)

作为替代方案,并且因为您已经设置了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      ; \  Keep these close together
mov  sp, bp      ; / 

push 'A'         ; This writes 0000h:7BFEh

mov  bx, 0007h   ; DisplayPage and GraphicsColor
mov  al, [bp-2]  ; This uses SS by default
mov  ah, 0Eh     ; BIOS.Teletype
int  10h
Run Code Online (Sandbox Code Playgroud)

ORG 0200h

我已经包含了这个,以表明一个线性地址有许多转换为 segment:offset。

ORG 0200h表示代码的第一个字节将位于偏移量 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      ; \  Keep these close together
mov  sp, bp      ; / 

push 'A'         ; This writes 07A0h:01FEh

mov  bx, 0007h   ; DisplayPage and GraphicsColor
mov  al, [bp-2]  ; This uses SS by default
mov  ah, 0Eh     ; BIOS.Teletype
int  10h
Run Code Online (Sandbox Code Playgroud)

您还可以使用 获取字符mov al, [01FEh]