【问题标题】:Assembly language bootloader code problem汇编语言引导加载程序代码问题
【发布时间】:2019-11-18 16:08:48
【问题描述】:

我正在尝试了解引导加载程序的内容,但在下面给出的代码部分遇到了一些问题,请帮助。我在这里提到 cmets,这将对您有所帮助,为什么我们使用 07C0h,它是固定位置还是任意位置,那么第二行中的 544 是什么。

Bootloader_start:    
mov ax, 07C0h        ;set up 4k of stack space above buffer
add ax, 544 ;8k buffer = 512 paragraphs + 32 paragraphs 
                      ;(loader) 

cli                  ;disable interrupts while changing stack
mov ss, ax 
mov sp, 4096
sti                  ;restore interrupts

mov ax, 07C0h ;set data segment to where we are loaded
mov ds, ax

cmp dl, 0
je no_change
mov [bootdev], dl    ;save boot device number   
mov ah, 8                 ;get drive parameters
int 13h
jc fatal_disk_error
and cx, 3fh              ;maximum sector number 
mov [SectorsPerTrack], cx  ;Sector numbers start at 1
movzx dx, dh        ;maximum head number
add dx, 1.             ;head number starts at 0 - add 1 for total
mov [Sides], dx

......继续

【问题讨论】:

  • 这既过于宽泛,又缺少可以使更多内容更有意义的上下文。为什么有人会写mov ax, imm16 / add ax, imm16 而不仅仅是mov ax, 07c0h + 544?如果你要使用像 movzx 这样的 386 条指令,为什么要解决 early-stepping-8086 错误,其中 mov ss, reg 直到下一条指令结束才禁用中断?
  • 如果没有任何具体问题,答案必须非常庞大,才能为每条指令和更高级别的每组指令以及 BIOS 调用提供足够的详细信息...发布您理解的内容什么都没有,让 SO 给你写一个教程不是我们在这里做事的方式。
  • 从字面上查找有关引导加载程序的任何内容,它将解释 ABI 用于 BIOS 将 MBR 加载到线性地址 7C00h,这就是引导扇区通常使用 org 7c00h 并设置 DS= 的原因0 或org 0 并设置 DS=07C0h。 (不幸的是,您只能相信这些;一些 BIOS 违反了书面标准,将 CS:IP 设置为正确的线性地址,但没有记录在案的 seg:off。)
  • mov ax, 07C0h add ax, 288 ; (512 + 4096) / 16 = 288 mov ss, ax 这将堆栈段 (ss) 的开头放在段号 07C0h + 288 处。引导加载程序在段号 07C0h 的开头加载。引导加载程序的大小为 512 字节,每个段为 16 字节。这意味着堆栈段在引导加载程序结束后的 4096 字节处开始。
  • 嗨,彼得,感谢您的帮助。正如我所给出的,我在堆栈溢出中发现了一些旧行,请帮助我理解为什么我们将值 288 放入 AX

标签: assembly x86-16


【解决方案1】:
Bootloader_start:    
mov ax, 07C0h   ;set up 4k of stack space above buffer
add ax, 544     ;8k buffer = 512 paragraphs + 32 paragraphs (loader) 

cli             ;disable interrupts while changing stack
mov ss, ax 
mov sp, 4096
sti             ;restore interrupts

mov ax, 07C0h   ;set data segment to where we are loaded
mov ds, ax

首先是明显的优化,它可以避免 Peter 关于不使用装配时添加的正确批评:

Bootloader_start:    
mov ax, 07C0h  ;set up 4k of stack space above buffer
MOV DS, AX
add ax, 544    ;8k buffer = 512 paragraphs + 32 paragraphs (loader) 
cli            ;disable interrupts while changing stack
mov ss, ax 
mov sp, 4096
sti            ;restore interrupts

那为什么是 544?

作者希望有一个 8192 字节的缓冲区加上一个 4096 字节的堆栈,位于引导加载程序的正上方,它位于内存中线性地址 7C00h 处。

知道线性地址 7C00h 是段落 07C0h 的情况下进行数学运算:

              Paragraph
              ---------
                07C0h    Bootloader 512 bytes ==  32 paragraphs (20h)
07C0h + 0020h = 07E0h    Buffer    8192 bytes == 512 paragraphs (200h)
07E0h + 0200h = 09E0h    Stack     4096 bytes
                                                 ---
                                                 544

堆栈的底部位于09E0h 段,即07C0h + (32 + 512) 或07C0h + 544。
然后将堆栈指针SP 设置为偏移量4096,因此我们有一个完整的SS:SP。

【讨论】:

    猜你喜欢
    • 2011-12-23
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多