尝试从磁盘(从同一文件)读取数据,将另外2个512字节扇区加载到内存中。磁盘读取功能如下:
; read DH sectors to ES:BX from drive DL
disk_read:
push dx
push bx ; Tried to check if disk is ready first, this code runs without errors
mov ah, 0x10
int 0x13
jc disk_not_ready
mov bx , DISK_CURRENT_STATUS_MSG
call print_string
mov bx, 0
mov bl , ah
call print_hex
pop bx
mov ah , 0x42 ; BIOS read sector function
mov al , dh ; Read DH sectors
mov ch , 0x00 ; Select cylinder 0
mov dh , 0x00 ; Select head 0
mov cl , 0x02 ; Start reading from second sector (i.e.
; after the boot sector)
int 0x13 ; BIOS interrupt to read from disk
jc disk_read_error_general ; Jump if error (i.e. carry flag set)
pop dx ; Restore DX from the stack
cmp dh , al ; if AL (sectors read) != DH (sectors expected)
jne disk_read_error_number_of_sectors_read_differs ; display error message
cmp dh , al ; if AL (sectors read) != DH (sectors expected)
je disk_read_success ; display success message
disk_read_exit:
ret
disk_read_success:
mov bx , DISK_READ_SUCCESS_MSG
call print_string
jmp disk_read_exit
disk_read_error_general:
mov bx , DISK_READ_ERROR_GENERAL_FAIL_MSG
call print_string
mov bx , DISK_CURRENT_STATUS_MSG
call print_string
mov bx, 0
mov bl , ah
call print_hex
jmp $
disk_not_ready:
mov bx , DISK_NOT_READY_ERROR_MSG
call print_string
jmp $
disk_read_error_number_of_sectors_read_differs:
mov bx , DISK_READ_ERROR_NUMBER_OF_SECTORS_DIFFERS_MSG
call print_string
jmp $
; Variables
DISK_READ_SUCCESS_MSG:
db "Disk read were successful!" , 0
DISK_NOT_READY_ERROR_MSG:
db "Disk is not ready for reading!" , 0
DISK_READ_ERROR_GENERAL_FAIL_MSG:
db "Disk read error, carry in CF were not set!" , 0
DISK_READ_ERROR_NUMBER_OF_SECTORS_DIFFERS_MSG:
db "Disk read error, number of sectors read differs from requested!" , 0
DISK_CURRENT_STATUS_MSG:
db "Disk status:" , 0
呼叫代码:
; Read some sectors from the boot disk using our disk_read function
[org 0x7c00]
mov [BOOT_DRIVE] , dl
mov bp , 0x8000
mov sp , bp
mov bx , 0x9000
mov dh , 3 ; Load 3 sectors to 0x0000 (ES):0x9000 (BX)
; from the boot disk.
mov dl , [BOOT_DRIVE]
call disk_read
mov dx , [0x9000]
call print_hex ; Print out the first loaded word , which
; we expect to be 0xdada , stored
; at address 0x9000
mov dx , [0x9000+512] ; Also , print the first word from the
call print_hex ; 2 nd loaded sector : should be 0xface
jmp $
%include "print_string.asm"
%include "print_hex.asm"
%include "disk_read.asm"
; Global variables
BOOT_DRIVE: db 0
; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55
times 256 dw 0xdada
times 256 dw 0xface
为什么第一个磁盘状态为0x0380,以及如何解决此超时错误(从此处检查错误代码:http://www.ctyme.com/intr/rb-0606.htm)? 硬盘驱动器是SSD类型的,但是在这里可能不相关,因为它是向后移植到常规驱动器(NASM: how to access ssd drive correctly?)的地址。 更新 print_string:
; Print string function, note that this code written after jmp $ instruction,
; otherwise the string were printed twice
print_string:
push ax ; pushing two registers that used onto a stack
push bx
mov ah , 0x0e ; int 10/ ah = 0 eh -> scrolling teletype BIOS routine
loop:
mov al, [bx] ; put ascii value in bx (lower bits) into al
int 0x10 ; print what in al
inc bx ; increment bx through the string
cmp al, 0 ; check if passed null-terminator
jnz loop ; loop until null terminator met
mov al, 0x0a ; line feed and carriage return added after line
int 0x10
mov al, 0x0d
int 0x10
pop bx ; popping two registers that used from stack
pop ax
ret
print_hex:
; Print hex function, note that this code written after jmp $ instruction,
; otherwise the string were printed twice
print_hex:
push ax ; pushing registers that used onto a stack
push dx
push bx
push cx
push si
mov si, 4
mov bx, dx
print_hex_loop:
dec si
cmp si, -1
je print_hex_loop_exit
mov dx, 0
mov ax, bx
mov cx, 16
div cx
mov bx, ax
mov ah, 0x0e ; int 10/ ah = 0 eh -> scrolling teletype BIOS routine
add dx, 0x0030
cmp dx, 0x0039
jg add_0x27_to_letter
print_hex_loop_continue:
mov al, dl
;int 0x10 ; print what in al
mov [HEX_OUTPUT_STR+si+2], al
jmp print_hex_loop
add_0x27_to_letter:
add dx, 0x0027
jmp print_hex_loop_continue
print_hex_loop_exit:
mov bx, HEX_OUTPUT_STR
call print_string
pop si ; popping registers that used from stack
pop cx ; popping registers that used from stack
pop bx
pop dx
pop ax
ret
HEX_OUTPUT_STR:
db "0x0000", 0
更新2 :修复了print_hex函数以dx而不是bx(在disk_read.asm中)打印(在使用时仔细推入并弹出堆栈),并从 int 13 / ah = 0x42 到 int 13 / ah = 0x02 (否则我的状态为 01h =“ AH中的功能无效或参数无效”),我已经磁盘状态为 0Ch ,即“磁盘不受支持或媒体无效”。有什么想法为什么会这样?