如何在x86实模式下正确设置SS,BP和SP? [英] How to properly setup SS, BP and SP in x86 Real Mode?

查看:291
本文介绍了如何在x86实模式下正确设置SS,BP和SP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何正确执行此操作,因为我的操作方式无效.

I want to know how to properly do it, because the way I'm doing it isn't working.

用7C00h设置BP寄存器,然后用BP设置SP寄存器,然后压入一些ASCII码,然后从存储器中获取数据并用INT 10h打印时,它就可以正常工作.

When setting the BP register with 7C00h, then setting the SP register with BP, then pushing some ASCII, then getting the data from the memory to print it with INT 10h, it works just fine.

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

push 'A'

mov ah, 0Eh
mov al, [7BFEh]
int 10h

实际输出是

A

但是当我这样做时:

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

...

它停止工作.调用了中断,光标移动了,但是什么也没打印.同样将SS设置为0也不起作用.请帮忙.

It stops working. The interrupt is called, the cursor moves, but nothing is printed. Also setting SS to 0 doesn't work. Please give a hand.

推荐答案

看该7C00h值,您可能正在使用引导加载程序.
并且您希望堆栈驻留在引导加载程序的下方.

Looking at that 7C00h value, you're probably working on a bootloader.
And you want the stack to reside below the bootloader.

您必须做出的一个重要选择将是如何继续执行启动时有效的分段寻址方案.

An important choice that you have to make will be how you want to proceed with the segmented addressing scheme that is in effect at start-up.

这表明代码的第一个字节将在偏移量7C00h处.为了使其正常工作,您必须将段寄存器初始化为0000h.请记住,引导加载程序是由BIOS在线性地址00007C00h加载的,该地址等效于segment:offset对0000h:7C00h.
如果要更改SP寄存器,则还要更改SS段寄存器.您不知道它在代码开始时包含的内容,您(大多数)应始终一前一后地修改这些寄存器.首先分配SS,然后直接分配SP. movpopSS会阻止此指令与以下指令之间的多种中断,以便您可以安全地设置一致的(2-寄存器)堆栈指针.

This indicates that the first byte of the code will be at offset 7C00h. For this to work well, you'll have to initialize the segment registers to 0000h. Remember that the bootloader was loaded by BIOS at linear address 00007C00h which is equivalent to segment:offset pair 0000h:7C00h.
If you're going to change the SP register, then also change the SS segment register. You don't know what it contains at the start of your code and you should (most) always modify these registers in tandem. First assign SS and directly after assign SP. A mov or a pop to SS blocks many kinds of interruptions between this and the following instruction so that you can safely set a consistent (2-register) stackpointer.

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      ; \  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

作为替代方法,并且由于已设置BP=7C00h,因此可以通过
读取堆叠的字符 mov al, [bp-2].

As an alternative and because you've setup BP=7C00h, you could read the stacked character via
mov al, [bp-2].

这表明代码的第一个字节将在偏移量0000h处.为了使其正常工作,您必须将某些段寄存器初始化为07C0h.请记住,引导加载程序是由BIOS在线性地址00007C00h加载的,该地址等效于segment:offset对07C0h:0000h.

This indicates that the first byte of the code will be at offset 0000h. For this to work well, you'll have to initialize some of the segment registers to 07C0h. Remember that the bootloader was loaded by BIOS at linear address 00007C00h which is equivalent to segment:offset pair 07C0h:0000h.

由于堆栈必须位于引导加载程序的之下,因此SS段寄存器将不同于其他段寄存器!

Because the stack must go below the bootloader, the SS segment register will be different from the other segment registers!

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

ORG 0200h

我已经包括了这一点,以表明线性地址可以对segment:offset进行许多转换.

ORG 0200h

I've included this one to show that a linear address has many translations to segment:offset.

ORG 0200h表示代码的第一个字节将在偏移量0200h处.为了使其正常工作,您必须将段寄存器初始化为07A0h.请记住,引导加载程序是由BIOS在线性地址00007C00h加载的,该地址等效于segment:offset对07A0h:0200h.

ORG 0200h indicates that the first byte of the code will be at offset 0200h. For this to work well, you'll have to initialize the segment registers to 07A0h. Remember that the bootloader was loaded by BIOS at linear address 00007C00h which is equivalent to segment:offset pair 07A0h:0200h.

由于512字节的堆栈位于引导加载程序的下方,因此SS段寄存器将再次等于其他段寄存器!

Because the 512-bytes stack goes below the bootloader, the SS segment register will again be equal to the other segment registers!

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

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

You can also fetch the character with mov al, [01FEh].

这篇关于如何在x86实模式下正确设置SS,BP和SP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆