【问题标题】:I can't read a sector from a CD-ROM in x86 assembly我无法从 x86 程序集中的 CD-ROM 中读取扇区
【发布时间】:2014-10-16 17:58:12
【问题描述】:

我正在尝试从我的 ISOSYS 引导加载程序为我的 OS32 操作系统加载第二阶段引导加载程序,但我似乎做不到。 CF 似乎总是被设置。这是从 CD/DVD 启动的,我使用的是 Debian GNU/Linux 7.6 (Wheezy)

这里是 isosys.asm:

;===============================================================
;
;               ISOSYS v1.0 in isosys.asm
;
; Program for booting OS32 and OS32-based systems from CD/DVDs
; using the ElTorito boot standard.
;
; By Omar, 2014
;
; ===============================================================

; set up bios...
bits 16
org 0x7c00

; beginning of sector 1, byte 0:

; jump over functions block
jmp Start

;
; Print()
;      prints a string to standard output
; AL = 0 : terminate
;

Print:
   lodsb            ; grab a byte from SI and place it in AL
   cmp al, 0         ; is AL = 0?
   jc PrintDone         ; yep, we're done so return
   mov ah, 0eh
   int 0x10         ; nope, print the character
   jmp Print         ; loop until no more characters to be printed
PrintDone:
   ret            ; return to wherever we were!

;
; Start()
;      bootloader entry point
;

Start:
   mov si, creditmsg
   call Print         ; print the first message
   mov dh, 1         ; read 1 sector

.ReadSector:
   cli            ; disable interrupts
   push dx            ; push this stack value
   sti            ; re-enable interrupts

   mov ax, 0x1000         ; read sector into address 0x1000
   xor bx, bx         ; read sector into offset 0x0
   mov ah, 0x02         ; read sector function
   mov al, dh         ; read 1 sector
   mov ch, 0x0         ; must be 0x0 to read sector
   mov dh, 0         ; reading head 0
   mov cl, 0x02         ; start reading from sector 2 to load the second stage

   mov [CDDriveNumber], dl      ; store our drive number is variable CDDriveNumber
   cli            ; disable interrupts
   pusha            ; save the stack
   sti            ; enable interrupts

   int 0x13         ; INT 13h
   jc Error         ; handle error because Carry Flag is set

   pop dx            ; Restore DX

.ExecuteSector:
   ; now that our sector was loaded into address 0x1000:0x0, let's execute it!
   jmp 0x1000:0x0         ; jump to execute the sector
;
; Error()
;      handles errors when carry is set
;

Error:
   mov si, errmsg
   call Print         ; print an error message

   cli            ; disable interrupts to prevent problems
   hlt            ; halt the system... :(

; data section

creditmsg db "ISOSYS v1.0 by Omar Mohammad, Init...", 0
errmsg db "Cannot load the second stage. (File not found maybe?)", 0
CDDriveNumber db 0

times 2048 - ($-$$) db 0      ; fill in 2048 bytes with zeroes

; end of sector 1! :D Any more code here would take bytes 2048 and 2049 but we don't    need that...

这是boot.asm,第二阶段:

bits 16
org 0x1000

Main:
   xor bx, bx
   mov ah, 0eh
   mov al, 'A'
   int 0x10

   cli
   hlt

times 2048 - ($-$$) db 0

我用nasm -f bin isosys.asm -o ISOSYSnasm -f bin boot.asm -o BOOT 编译 然后我做了mkdir iso 然后cp ISOSYS iso/ 然后cp BOOT iso/ 然后生成ISO: genisoimage -no-emul-boot -boot-load-size 4 -eltorito-boot ISOSYS -o boot.iso iso/

我在 VirtualBox 中运行它,但它说的是无法加载第二阶段(可能找不到文件?),这意味着设置了携带标志,但我似乎找不到错误。

对任何人有帮助吗?帮助将不胜感激! :*

【问题讨论】:

  • 我相信-no-emul-boot 专门轮流磁盘仿真,所以你已经搞砸了。即使没有,由于您已将 BOOT 放入单独的文件中,因此无法将其作为第二扇区访问。您应该将其附加到ISOSYS 并酌情使用软盘或高清仿真。
  • 谢谢你,但你能告诉我如何在 linux 上使用软盘仿真和 genisoimage 吗?谢谢:*

标签: assembly load cd sector cd-rom


【解决方案1】:

您的堆栈处理完全关闭。您将dx(为什么?)推入clisti 块(为什么?),然后pusha,但不要popa

mov ax, 0x1000 后面还缺少一个 mov es,ax,用于实际将段寄存器设置为您希望加载代码的位置。

您无法使用 CHS 功能 (AH=02h) 读取 ISO,您必须使用带有参数块的 LBA 功能 (AH=42h)。 Have an example.

【讨论】:

    猜你喜欢
    • 2014-09-16
    • 2014-08-26
    • 2020-10-11
    • 2011-01-11
    • 2012-03-29
    • 1970-01-01
    • 2017-01-29
    • 2012-07-25
    • 2016-02-15
    相关资源
    最近更新 更多