1

我正在学习实模式编程,并在这里找到了一篇关于 SO 的帖子,这对我来说非常有用但我对给定代码中的工作方式有些疑问

基本 NASM 引导程序

  ;This is NASM

    BITS 16                 ; 16 bits!

    start:                          ; Entry point
    mov ax, 07C0h           ; Move the starting address (after this bootloader) into 'ax'
    add ax, 288             ; Leave 288 bytes before the stack beginning for some reason
    mov ss, ax              ; Show 'stack segment' where our stack starts
    mov sp, 4096            ; Tell 'stack pointer'  that our stack is 4K in size

    mov ax, 07C0h           ; Use 'ax' as temporary variable for setting 'ds'
    mov ds, ax              ; Set data segment to where we're loaded


    mov si, text_string     ; Put string position into SI (the reg used for this!)
    call print_string       ; Call our string-printing routine

    jmp $                   ; Jump here - infinite loop!

     text_string db 'This is my cool new OS!', 0 ; Our null terminated string

                                                ; For some reason declared after use


   print_string:                   ; Routine: output string in SI to screen
    mov ah, 0Eh             ; I don't know what this does..
                            ; Continue on to 'repeat'
   .repeat:
    lodsb                   ; Get character from DS:SI into AL
    cmp al, 0               ; If end of text_string
    je .done                ; We're done here
    int 10h                 ; Otherwise, print the character (What 10h means)
    jmp .repeat             ; And repeat

   .done:
    ret

    times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
    dw 0xAA55               ; The standard PC 'magic word' boot signature

1)DS和CS在这里重叠吗?

2)CS是否从0h位置开始?在此处输入图像描述,所附图像显示了 512 个字节,它们是由汇编器生成的引导扇区

3)DS和CS都是从07c00H开始的吗??首先,代码部分是在放入文本字​​符串的数据之前填写的

4)堆栈从07c00+288开始??并且 mov sp,4096 将定义大小为 (07c00+288+4096-07c00+288) 的堆栈。

4

2 回答 2

1

简短的回答:是的。实模式段:偏移地址可以并且确实重叠。您的 BIOS 在 7C00h 加载引导扇区。这可能是cs零,偏移 7C00h(尽管有传言说某个 Compac Presario BIOS 在 07C0:0000 加载)。这是同一个地址!我们乘以 16,因为这是在实模式下计算地址的方式 - 段乘以 16 加上偏移量。我们可以通过将一个数字向左移动 4 位来乘以 16——一个十六进制数字,如果你这样看的话。

org 7C00hbootsector在顶部说是很常见的。由于此代码没有org,因此 Nasm 假定org 0. 在这个“通用”引导扇区中,我们将 0 放入ds(和es?)。org 0我们想要 7C0h在ds. 0000:7C00h 和 07C0h:0000 是相同的地址。找到这一点很重要text_string

您发现的代码中的注释有点欺骗性......它并不是真正的“288 字节”。将其写为 hex - 120h 可能更容易。将其加到 7C0h 中得到 8E0h。然后sp装入十进制的 4096,即 1000h。所以堆栈的线性地址(段 * 16 + 偏移量)从 9E00h 开始向下工作到 8E00h - 有足够的空间来避免在 7C00h 到 7E00h 遇到代码(512 十进制 = 200h 是引导扇区的大小)。

可能值得注意的是,您的“数据”位于代码中间,但它处于不会执行的位置,所以没关系。

我希望我的算术是正确的,并且没有让你更糟!

于 2013-07-15T17:03:10.437 回答
0
mov ax, 07C0h           ; Move the starting address (after this bootloader) into 'ax'
add ax, 288             ; Leave 288 bytes before the stack beginning for some reason
mov ss, ax              ; Show 'stack segment' where our stack starts

这将设置您的堆栈段。段寄存器是地址中的第 4 位到第 19 位。因此,您的堆栈段从地址07C00h + 288*16或开始08180h(您将 288 十进制添加到ax其中07C0h然后将其移至段寄存器)。

mov sp, 4096            ; Tell 'stack pointer'  that our stack is 4K in size

仅当您知道地址范围可用于堆栈08180h时,这才会为您提供 4k 堆栈。0917Fh

mov ax, 07C0h           ; Use 'ax' as temporary variable for setting 'ds'
mov ds, ax              ; Set data segment to where we're loaded

这会将数据段设置为从 address 开始07C00h

我从您的列表中不知道您的代码段从哪里开始或设置为什么,cs因此不清楚是否重叠。不正常启动。csdscs0

于 2013-07-15T14:35:25.383 回答