Code: Select all
No Error.
A1B2C3
0100
On real hardware however, (Specifically on a 32-bit Intel from the Celeron family and a 64-bit AMD FX-8320) it outputs:
Code: Select all
No Error.
000000
0100
Code: Select all
[org 0x7c00]
[bits 16]
; Init segment registers
mov bx, 0x0
mov ds, bx
mov ss, bx
mov es, bx
mov fs, bx
mov gs, bx
; Setup Stack
mov bp, 0x9000
mov sp, bp
; Save this number, it's our boot drive by default
mov [BOOT_DRIVE], dl
; After the boot sector, some data is included which must be loaded from the disk manually.
mov ah, 0x02 ; Read sectors from disk
mov ch, 0 ; Cylinder 0
mov dh, 0 ; Head 0
mov cl, 2 ; Sector 2
mov al, 1 ; Read 1 sector
; Data will be read to es:bx
mov bx, data
int 0x13
push ax ; Save the status
jc disk_error
mov bx, nermsg
call prn_str
mov bx, data
mov cx, 3
call prn_hex
jmp post_disk_error_check
disk_error:
mov bx, errmsg
call prn_str
post_disk_error_check:
; Move the cursor to the next line
mov ah, 0x0e
mov al, 10
int 0x10
mov al, 13
int 0x10
; Prints out two bytes: al (Number of sectors read), and ah (status). These values were saved to the stack immediately after the interrupt.
mov bx, sp
mov cx, 2
call prn_hex
pop ax
jmp $
%include "lib/prn_str.asm"
%include "lib/prn_hex.asm"
errmsg: db "General disk read error.", 10, 13, 0
nermsg: db "No error.", 10, 13, 0
BOOT_DRIVE: db 0
times 510-($-$$) db 0
dw 0xaa55
data:
db 0xA1, 0xB2, 0xC3
times 1024-($-$$) db 0
Code: Select all
; Prints a null terminated ASCII string using the int 10h teletype routine.
; Takes: BX as pointer to start of string
prn_str:
push ax
push bx
mov ah, 0x0e
prn_str_loop:
; Get value at pointer
mov al, [bx]
; Check for null value
cmp al, 0
je prn_str_ret
int 0x10
inc bx
jmp prn_str_loop
prn_str_ret:
pop bx
pop ax
ret
Code: Select all
; Prints the 16-bit hexadecimal value pointed to using the int 10h teletype routine.
; Takes: BX as pointer to first value to print, CX as number of values to print
prn_hex:
push ax
push bx
push cx
mov ah, 0x0e
prn_hex_loop:
cmp cx, 0
je prn_hex_end ; If number of bytes remaining is zero, quit
mov al, [bx] ; Isolate the current significant byte, at bx
shr al, 0x04 ; Isolate the most significant 4 bits
cmp al, 0xA ; Test if this value is represented by a number (<10) or a letter (>=10)
jl prn_hex_high_is_number
; high is a letter
add al, 55
int 0x10
jmp prn_hex_high
prn_hex_high_is_number:
; high is a number
add al, 48
int 0x10
prn_hex_high:
mov al, [bx] ; Isolate the current significant byte, at bx
and al, 0x0F ; Isolate the least significant 4 bits
cmp al, 0xA ; Test if this value is represented by a number (<10) or a letter (>=10)
jl prn_hex_low_is_number
; low is a letter
add al, 55
int 0x10
jmp prn_hex_low
prn_hex_low_is_number:
; low is a number
add al, 48
int 0x10
prn_hex_low:
; Now that this byte is printed, get to next byte and decrement the number of bytes remaining counter (cx)
inc bx
dec cx
jmp prn_hex_loop
prn_hex_end:
pop cx
pop bx
pop ax
ret