title: I can't read a sector from a CD-ROM in x86 assembly
body: <p>I'm trying to load the second stage bootloader from my ISOSYS bootloader for my OS32 operating system, but I can't seem to do it. CF seems to always be set. This is to be booted from a CD/DVD and I'm using Debian GNU/Linux 7.6 (Wheezy)</p>
  
  <p>Here's isosys.asm:</p>
  
  <pre><code>;===============================================================
  ;
  ;               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...
  </code></pre>
  
  <p>This is boot.asm, the second stage:</p>
  
  <pre><code>bits 16
  org 0x1000
  
  Main:
     xor bx, bx
     mov ah, 0eh
     mov al, 'A'
     int 0x10
  
     cli
     hlt
  
  times 2048 - ($-$$) db 0
  </code></pre>
  
  <p>I compiled with <code>nasm -f bin isosys.asm -o ISOSYS</code> and <code>nasm -f bin boot.asm -o BOOT</code>
  Then I did <code>mkdir iso</code> and then <code>cp ISOSYS iso/</code> then <code>cp BOOT iso/</code> and then generated ISO:
  <code>genisoimage -no-emul-boot -boot-load-size 4 -eltorito-boot ISOSYS -o boot.iso iso/</code></p>
  
  <p>I run it in VirtualBox but all it says is Cannot load the second stage (file not found maybe?) which means that Carry Flag is set but I can't seem to find the error.</p>
  
  <p>Any help anyone?  Help would be greatly appreciated! :*</p>