DS和CS是否在此代码中重叠

时间:2013-07-15 14:11:59

标签: assembly x86 real-mode

我正在以实模式学习编程,并在SO上发现了一篇对我来说非常有用的帖子 但我对在给定代码中如何工作有一些疑问

Basic NASM bootstrap

  ;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位置开始?enter image description here,附加的图像显示由汇编程序生成的512个字节的引导扇区

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

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

2 个答案:

答案 0 :(得分:1)

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

引导程序通常在顶部说org 7C00h。由于此代码没有org,因此Nasm假设org 0。在这个“常见”引导程序中,我们将{0}放入ds(和es?)。使用org 0,我们需要ds中的7C0h。 0000:7C00h和07C0h:0000是相同的地址。找到text_string非常重要。

你发现的代码中的注释有点欺骗性......它实际上不是“288字节”。将其写成十六进制可能更容易 - 120h。将其加到7C0h得到8E0h。然后sp加载4096十进制或1000h。因此,堆栈的线性地址(段* 16 +偏移)从9E00h开始向下工作到8E00h - 有足够的空间避免在7C00h到7E00h时碰到你的代码(512位小数= 200h是bootsector的大小)。 / p>

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

我希望我的算术运算正确,并且没有让你更加困惑!

答案 1 :(得分: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*1608180h开始(您向ax添加了288位小数,其中包含07C0h然后您移动了到段寄存器)。

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

只有当您知道地址范围08180h0917Fh可用于堆栈时,才会为您提供4k堆栈。

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

这会将数据段设置为从地址07C00h开始。

我不知道您的列表中的代码段开始位置或cs设置的位置,因此不清楚csds是否重叠。 cs通常不会从0开始。