簡體   English   中英

如何在NASM程序集中使用BIOS int 13h從磁盤加載內核?

[英]How to load a kernel from disk with BIOS int 13h in NASM assembly?

我已經堅持了好幾個星期了,並且不知道我哪里出錯了,因為NASM沒有給我任何錯誤。 由於評論,代碼非常自我解釋。

這是從BIOS加載的代碼

 ;--------------------------------------------
 ; 'boot.asm'
 ; loaded from BIOS

 [org 0x7C00]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

 resetdisk:
  mov ah, 0x00  ; reset function
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc resetdisk

 readdisk:
  mov bx, 0x8000  ; segment
  mov es, bx
  mov bx, 0x0000  ; offset

  mov ah, 0x02  ; read function
  mov al, 0x03  ; sectors
  mov ch, 0x00  ; cylinder
  mov cl, 0x02  ; sector
  mov dh, 0x00  ; head
  mov dl, 0x00  ; drive
  int 0x13   ; disk int
  jc readdisk
  jmp [es:bx]   ; buffer

 ;--------------------------------------------

 times 510 - ($ - $$) db 0x00
 db 0x55, 0xAA

這是應該(但未加載)的代碼

 ;--------------------------------------------
 ; 'load.asm'
 ; loaded from 'boot.asm'

 [org 0x8000]
 [bits 16]

 ;--------------------------------------------

 main:
  mov ah, 0x0E  ; print function
  mov al, '.'   ; ascii char
  int 0x10   ; IO int

  jmp $    ; hang

任何幫助將不勝感激。

帕特里克

jmp [es:bx]不會跳轉到地址es:bx 此命令幾乎跳轉到es:bx存儲在單詞中的地址。 這就是為什么許多較舊的匯編程序使你將這種指令拼寫為jmp word ptr [es:bx]或甚至是jmp near ptr [es:bx] ; 這種方式更清楚將會發生什么。 您可能想要的是遠離固定位置:

; jmp far 8000:0000
db 0eah
dw 00000h ; offset
dw 08000h ; segment

如果你想跳轉到es:bx ,請使用retf

push es
push bx
retf

我不確定你要用代碼實現什么,但如果我理解正確,你想從磁盤讀取幾個扇區到0x8000位置,然后執行該代碼?

如果是這種情況,那么你將不得不明確地向該特定位置發出CALL / JUMP。 BIOS不會為您調用該代碼。 在啟動時,初始化BIOS后,它會將指令指針IP設置為地址0x7c00。 然后cpu將開始按順序執行代碼,因此,如果沒有JMP / CALL到0x8000,它將不會執行0x8000處的代碼,直到它執行0x7c00到0x8000之間的每個內存地址等。

所以解決方案是在你的jc readdisk之后有一個jmp或call指令。

如果我的理解不正確,那么我道歉。 希望這可以幫助。

INT13的一個問題是磁頭和磁道編號從0開始,但扇區編號由於某種原因從1開始。您可能會檢查您的扇區寫入實用程序是否符合此編號方案。

問題:

  • 你在開機時看到多少個點?
  • 軟盤馬達是否開啟?

我不知道你是否正在使用軟盤來啟動你的操作系統,但如果你正在使用,我建議你在ORG和Bits聲明之后聲明一些事情,看看(它們非常重要):

JMP short main   ; Jump past disk description section
NOP              ; Pad out before disk description

; ------------------------------------------------------------------
; Disk description table, to make it a valid floppy
; Note: some of these values are hard-coded in the source!
; Values are those used by IBM for 1.44 MB, 3.5 diskette

OEMLabel            db "BERL OS"    ; Disk label - 8 chars
BytesPerSector      dw 512          ; Bytes per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; Reserved sectors for boot record
NumberOfFats        db 2            ; Number of copies of the FAT
RootDirEntries      dw 224          ; Number of entries in root dir
LogicalSectors      dw 2880         ; Number of logical sectors
MediumByte          db 0F0h         ; Medium descriptor byte
SectorsPerFat       dw 9            ; Sectors per FAT
SectorsPerTrack     dw 18           ; Sectors per track (36/cylinder)
Sides               dw 2            ; Number of sides/heads
HiddenSectors       dd 0            ; Number of hidden sectors
LargeSectors        dd 0            ; Number of LBA sectors
DriveNo             dw 0            ; Drive No: 0
Signature           db 41           ; Drive signature: 41 for floppy
VolumeID            dd 00000000h    ; Volume ID: any number
VolumeLabel         db "BERL OS"    ; Volume Label: any 11 chars
FileSystem          db "FAT12"      ; File system type: don't change!

; End of the disk description table
; ------------------------------------------------------------------

這個是個好主意。

問候。

我不確定為什么代碼不起作用,因為我無法檢查整個環境(磁盤,內存轉儲等)......但我能說的是......代碼錯了。 你正在加載第二個程序,而不是0x8000 (這是使用0rg 0x8000的點嗎?),但是在0x80000

原因是,您正在使用段:偏移尋址方式錯誤,地址0x8000:0x0000被解析為線性地址0x80000 ,因為段值向左移位4位,然后加到偏移量。

要解決此問題,您應該查看內存轉儲並查看程序是否按預期工作....或者您正在加載磁盤的錯誤扇區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM