2013-07-15 34 views
1

我在實模式下學習編程重疊,發現這裏的SO後這對我來說 相當有用的,但我有一個關於事情是如何在給定的代碼工作的一些疑慮是DS和CS在此代碼

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)的堆棧。

回答

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(您添加了288小數到ax,其中有07C0h然後您將其移至段寄存器)。

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

這使您只有當你知道地址範圍08180h通過0917Fh可供堆棧使用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處開始。

+0

但操作碼(這是代碼的一部分)從地址0開始,爲什麼288是由16這裏 –

+0

@AmitSinghTomar乘我不知道你的十六進制轉儲是什麼。但是它會在實際加載到內存之前經歷重定位過程。在CPU的文字地址爲'0'處有中斷向量等,所以代碼不可能從'0'開始。 – lurker

1

簡答:是的。實模式段:偏移地址可以並且重疊。您的BIOS在7C00h加載啓動扇區。這可能是cs零,偏移量7C00h(雖然有傳言說某個Compac Presario BIOS在07C0:0000加載)。這是同一個地址!我們乘以16,因爲這是地址在實模式下計算的方式 - 分段時間16加偏移量。如果你這樣看,我們可以通過將數字4位左移一位十六進制數字乘以16。

引導扇區在頂部說org 7C00h是很常見的。由於此代碼沒有org,納斯姆假設org 0。在這個「通用」引導扇區中,我們將0放入ds(和es?)。用org 0我們想要ds中的7C0h。 0000:7C00h和07C0h:0000是相同的地址。這對找到text_string很重要。

您發現的代碼中的評論有點欺騙......它不是真正的「288字節」。把它寫成hex - 120h可能會更容易。這被添加到7C0h給8E0h。然後sp加載了4096十進制或1000h。因此,線性地址(段* 16 +偏移)的堆疊開始於9E00h和向下工程8E00h - 足夠的空間,以避免碰撞到您的代碼在7C00h處到7E00h(512十進制= 200H是啓動扇區的尺寸)。

可能值得注意的是你的「數據」是在你的代碼中,但它是在它不會被執行的位置,所以也沒關係。

我希望我已經得到了算術權,並沒有讓你感到困惑差!

+0

感謝弗蘭克的回答,我理解你的意見是什麼,如果我們寫的組織100H,那麼CS = 0,抵消一部分將是100小時,如果是的話yoyr代碼段從0和第一條指令開始執行將處於偏移下一點乘以288和16,如上面所寫的(段* 16)段部分應該乘以16而不是偏移,但不是它288這裏是偏移量的一部分。 –