如何从加载在NASM装配BIOS INT 13H磁盘上的内核?(How to load a kern

2019-08-17 18:48发布

我一直坚持这个数周现在不知道我要去哪里错了,因为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

任何帮助将非常感激。

帕特里克

Answer 1:

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


Answer 2:

我不知道你正在努力实现的代码是什么,但如果我理解正确的话,你想从磁盘读取少数部门到地址0x8000,然后执行该代码?

如果是这样的话,那么你将不得不显式地拨打电话/跳转到特定位置。 BIOS将不会调用的代码你。 在引导过程中,一旦BIOS被初始化,它将设置指令指针IP的地址0x7c00。 然后,CPU将开始执行代码顺序,所以没有JMP / CALL为0x8000它不会执行在为0x8000的代码,直到它已执行其间0x7c00每个存储器地址为0x8000等

因此,解决办法是有一个JMP或您的JC readdisk后调用指令。

如果我的理解不正确,我道歉。 希望这可以帮助。



Answer 3:

与INT13有一个问题是,头和跟踪号码从0开始,但由于某种原因扇区编号从1开始你可能会检查你的部门书写工具符合这一编号方案。

问题:

  • 多少个点,你看,当你启动?
  • 是否软驱马达踢?


Answer 4:

我不知道,如果您使用的是软盘引导你的操作系统,但如果你正在使用的话,建议你申报ORG和位后声明一些东西,看看(他们是非常重要的):

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
; ------------------------------------------------------------------

这是把这个好主意。

问候。



Answer 5:

我不知道为什么代码不能正常工作,因为我无法检查整个环境(磁盘,内存转储等)...但我可以说的是......的编码是错误的。 您正在加载的第二个程序,而不是在0x8000 (这是用点0rg 0x8000吧?),但在0x80000

其原因是,正在使用的区段:偏移寻址以错误的方式,地址0x8000:0x0000被解析到线性地址0x80000 ,由于段值左移4位的然后加入到的偏移量。

要解决这个问题,你应该看看内存转储,看看该程序的工作,你希望它太....要么或你加载磁盘错误扇区。



文章来源: How to load a kernel from disk with BIOS int 13h in NASM assembly?