2013-03-29 58 views
0

我剛剛接近機器級別的x86編碼,所以請原諒我的問題的微不足道。以下代碼旨在成爲簡單的引導加載程序。它將軟盤的某個扇區轉儲到內存中,然後跳轉到加載的代碼。在加載的代碼中,我試圖從內存變量中讀取,但沒有成功,如註釋中所述。i386實模式。關於從內存加載數據的一些問題

[ORG 0] 

      jmp 07C0h:start  ; Goto segment 07C0 

    start: 
      ; Update the segment registers 
      mov ax, cs 
      mov ds, ax 
      mov es, ax 


    reset:      ; Reset the floppy drive 
      mov ax, 0   
      mov dl, 0   
      int 13h    
      jc reset   


    read: 
      mov ax, 1000h  ; ES:BX = 1000:0000 
      mov es, ax   
      mov bx, 0   

      mov ah, 2   ; Load disk data to ES:BX 
      mov al, 5   ; Load 5 sectors 
      mov ch, 0   ; Cylinder=0 
      mov cl, 2   ; Sector=2 
      mov dh, 0   ; Head=0 
      mov dl, 0   ; Drive=0 
      int 13h    ; Read! 

      jc read    ; on error 


      jmp 1000h:0000  ; Jump to the program 


    times 510-($-$$) db 0 
    dw 0AA55h 

     ;  == Loaded code from second floppy sector == 
prog: 
     mov  ah,  0x0E  ; Prints a char. This one works: the '-' 
     mov  al,  '-'  ; is printed. 
     mov  bx,  0 
     int  10h 

     mov  bx,  0 
a:         
     mov  al,  [L1+bx] ; Should read from L1 and print out chars. 
     inc  bx     ; But it prints only white spaces. Why? 
     int  10h 
     cmp  bx,  10 
     jz  h 
     jmp a 

     cli 
     hlt 

     L1 db ""  ; my string 

我不明白爲什麼它不起作用。我非常感謝任何幫助。

+0

只是爲了澄清,上面是一個單一的源文件或兩個? –

+0

你也可以給我們實際的代碼?缺少'h'標籤,沒有它,這個代碼就無法組裝。 –

+0

檢查我答案更新中的最後一句話 –

回答

2

而「裝載從軟盤」的一部分被編譯爲一個不同的基礎比它加載到一個偏移,則需要重新計算其地址

你也使用ORG 7C00h和饒了自己跳,區別在於您的細分將是0,而不是07C0h

您可以計算出新作[L1-PROG]偏移或者你可以重新排列你的代碼:

  jmp 1000h:000Ah  ; Jump to the program 
.... 
L1   db ""  ; my string 
prog: 
     mov  ah,  0x0E 

... 
     mov  al,  cs:[bx] 

我沒有彙編程序進行測試,但你得到想法 - r如果需要一個浮動地址,請將其放在開頭

我粗略地估計了段1000H中的實際偏移大約爲32-ish,這就是您翻譯後的L1大致會出現的位置。相反,你的L1計算的編譯時間約爲550,所以你實際上試圖從你讀的第二個扇區加載一些東西。第二個加載扇區的開頭是否有一些空白字符或零?

+0

@AlexeyFrunze哦,我現在看到 –

+0

事實上,第一個部門填充零,直到第二個到達。然後它打印出這些內存。那麼,我試着將'[L1 + bx]'改成'[L1-prog + bx]',並且它工作,但是隻有在另一個答案中設置ds寄存器之後纔可以。現在我很難接受答案。 :-)所以,段選擇符和偏移量都是錯誤的。謝謝你的幫助! – mghis

2

如果上述是單個彙編程序文件,更改jmp 1000h:0000jmp 0FE0h:200h,這將適當地補償ip寄存器偏移從一路從[ORG 0]累積並仍然控制轉移到物理地址0x10000

除此之外,在代碼的第二部分中設置dscs(或0FE0h)。

+0

DS被設置爲CS,開始時爲0,如果「Loaded from floppy」被加載在與之前的代碼相同的地址處,則會給出正確的地址 –

+0

@StenPetrov Nope。在執行代碼的第二部分時,我的意思是'ds'。在那裏時,'cs'!='ds'。 –

+0

我試着設置數據段寄存器。我在'prog:'後添加了以下內容:'mov ax,1000h','mov ds,ax',但沒有任何變化。 – mghis