title: BIOS Disk - Read Sectors Into Memory (int 0x13, ah=0x02) blocking
body: <p>I am writing a MBR and using <a href="http://wiki.qemu.org/Main_Page" rel="nofollow">QEMU</a> for testing.</p>
  
  <p>When using <a href="http://www.ctyme.com/intr/rb-0607.htm" rel="nofollow">read sectors into memory (<code>int 0x13, ah=0x02</code>)</a>, the <code>int</code> instruction seems to block execution of my program, and it proceeds to hang. I have tested this with various print statements to confirm that it is this particular instruction blocking.</p>
  
  <p>What could make the interrupt block? I thought this could only be done with the <code>cli</code> instruction, and even then it does not block <code>int</code> instructions.</p>
  
  <hr>
  
  <p>For context, this is the code leading up to the blocking interrupt in <code>read_sectors_16</code>:</p>
  
  <pre><code>        [bits 16]        
          [ORG 0x7C00]
          jmp 0x000:start_16      ; ensure cs == 0x0000
  
          reset_failure_str db 'error: boot disk reset', 13, 10, 0
          read_failure_str db 'error: boot disk read', 13, 10, 0
          boot_segaddr dw 0x7E00
  
          read_attempt_str db 'read attempt', 13, 10, 0
          end_read_attempt_str db 'end read attempt', 13, 10, 0
  
  start_16:
          ;; Initialize segment registers
          mov ax, cs
          mov ds, ax
          mov es, ax
  
          jmp load_bootsector_2            
  
  
  load_bootsector_2:              ; Read program from disk
          ;; dl set by BIOS to the drive number MBR was loaded from
          mov cx, 0x0002          ; cylinder 0, sector 2
          xor dh, dh              ; head 0
          mov al, 0x01            ; load 1 sector
          mov bx, boot_segaddr    ; destination - load right after the boot loader
          call read_sectors_16
          jnc .success
          mov si, read_failure_str
          call print_string_16        
          jmp halt                ; halt
  
          .success:        
          jmp boot_segaddr:0000   ; jump to program
  </code></pre>
  
  <p>And here is the function with the blocking interrupt:</p>
  
  <pre><code>;;; read_sectors_16
  ;;;
  ;;; Read sectors from disk in memory using BIOS services
  ;;;
  ;;; input:      dl      = drive
  ;;;             ch      = cylinder[7:0]        
  ;;;             cl[7:6] = cylinder[9:8]
  ;;;             dh      = head
  ;;;             cl[5:0] = sector (1-63)
  ;;;             es:bx   -&gt; destination
  ;;;             al      = number of sectors
  ;;;
  ;;; output:     cf (0 = success, 1 = failure)
  read_sectors_16:
          pusha
          mov di, 0x02            ; set attempts (max attempts - 1)
  
          .attempt:
          mov ah, 0x02            ; read sectors into memory (int 0x13, ah = 0x02)
          int 0x13                ; TODO: this call is not returning!
          jnc .end                ; exit if read succeeded
          dec di                  ; record attempt
          test di, di
          jz .end                 ; end if no more attempts
          xor ah, ah              ; reset disk (int 0x13, ah = 0x00)
          int 0x13
          jnc .attempt            ; retry if reset succeeded, otherwise exit
          jmp .end
  
          .end:
          popa
          ret
  </code></pre>