IPLでレジスタを表示する
デバッグしやすいように、レジスタ表示ルーチンを用意する。
以下の順で表示する。
IP(戻り先)
AX BX CX DX
SI DI BP SP
CS DS ES SS
BH, BL が int 10h AH=0eh の時に使われることがあるという情報があるので、DX レジスタを使う。
リロケータブルになるようにスタックを使用(スタックがメモリを破壊しないことが前提)
pusha/popa を使ってコード量を削減。80286 以降でなければ動かない。
セグメントレジスタはBIOSコールでは破壊されないという前提。
code:debug_ipl.asm
code segment use16
.486
assume cs:code
org 7C00h
start:
; ignore BIOS Parameter Block
call print_registers
jmp $ ; stop
print_registers:
pusha
mov bp, sp
; print IP
call print_dx_hex
call print_newline
; print AX
call print_dx_hex
call print_space
; print BX
call print_dx_hex
call print_space
; print CX
call print_dx_hex
call print_space
; print DX
call print_dx_hex
call print_newline
; print SI
call print_dx_hex
call print_space
; print DI
call print_dx_hex
call print_space
; print BP
call print_dx_hex
call print_space
; print SP
call print_dx_hex
call print_newline
; print CS
push cs
pop dx
call print_dx_hex
call print_space
; print DS
push ds
pop dx
call print_dx_hex
call print_space
; print ES
push es
pop dx
call print_dx_hex
call print_space
; print SS
push ss
pop dx
call print_dx_hex
call print_newline
popa
ret
print_space:
mov al, 20h ; space
call put_char
ret
print_newline:
mov al, 0Ah ; newline
call put_char
mov al, 0Dh ; carriage return
call put_char
ret
; break: ax, cx
print_dx_hex:
mov cx, 0404h ; CH = number of nibble, CL = number of shift
print_dx_hex_loop:
rol dx, cl
mov ax, 0e0fh ; AH = 0eh(BIOS print tty),
and al, dl
add al, 90h
daa
adc al, 40h
daa
int 10h
dec ch
jnz print_dx_hex_loop
ret
put_char:
mov ah, 0eh ; tty print character
int 10h
ret
db 510-($-start) dup(0) ; padding
dw 0aa55h ; boot sector signature
code ends
end start
古いコード。参考に残す。pusha/popa を使わない。8086でも動くはず。
code:debug_ipl_8086.asm
code segment use16
assume cs:code
org 7C00h
start:
; ignore BIOS Parameter Block
call print_registers
jmp $ ; stop
print_registers:
push bp
mov bp, sp
push cs
push ds
push es
push ss
push ax
push bx
push cx
push dx
push si
push di
; print IP
call print_dx_hex
call print_newline
; print AX
call print_dx_hex
call print_space
; print BX
call print_dx_hex
call print_space
; print CX
call print_dx_hex
call print_space
; print DX
call print_dx_hex
call print_newline
; print SI
call print_dx_hex
call print_space
; print DI
call print_dx_hex
call print_space
; print BP
call print_dx_hex
call print_space
; print SP
mov dx, bp
add dx, 2
call print_dx_hex
call print_newline
; print CS
call print_dx_hex
call print_space
; print DS
call print_dx_hex
call print_space
; print ES
call print_dx_hex
call print_space
; print SS
call print_dx_hex
call print_newline
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov sp, bp
pop bp
ret
print_space:
mov al, 20h ; space
call put_char
ret
print_newline:
mov al, 0Ah ; newline
call put_char
mov al, 0Dh ; carriage return
call put_char
ret
; break: ax, cx
print_dx_hex:
mov cx, 0404h ; CH = number of nibble, CL = number of shift
print_dx_hex_loop:
rol dx, cl
mov ax, 0e0fh ; AH = 0eh(BIOS print tty),
and al, dl
add al, 90h
daa
adc al, 40h
daa
int 10h
dec ch
jnz print_dx_hex_loop
ret
put_char:
mov ah, 0eh ; tty print character
int 10h
ret
db 510-($-start) dup(0) ; padding
dw 0aa55h ; boot sector signature
code ends
end start
古いコード。参考に残す。リロケータブルではない。
code:debug_ipl_old.asm
code segment use16
assume cs:code
org 7C00h
start:
call print_registers
jmp $ ; stop
print_registers:
; print AX
call print_dx_hex
call print_space
; print BX
call print_dx_hex
call print_space
; print CX
call print_dx_hex
call print_space
; print DX
call print_dx_hex
call print_newline
; print SI
call print_dx_hex
call print_space
; print DI
call print_dx_hex
call print_space
; print BP
call print_dx_hex
call print_space
; print SP
call print_dx_hex
call print_newline
; print CS
call print_dx_hex
call print_space
; print DS
call print_dx_hex
call print_space
; print ES
call print_dx_hex
call print_space
; print SS
call print_dx_hex
call print_newline
ret
print_space:
mov al, 20h ; space
call put_char
ret
print_newline:
mov al, 0Ah ; newline
call put_char
mov al, 0Dh ; carriage return
call put_char
ret
print_dx_hex:
; print DH upper nibble
mov al, dh
shr al, 1
shr al, 1
shr al, 1
shr al, 1
call nibble_to_ascii
call put_char
; print DH lower nibble
mov al, dh
and al, 0Fh
call nibble_to_ascii
call put_char
; print DL upper nibble
mov al, dl
shr al, 1
shr al, 1
shr al, 1
shr al, 1
call nibble_to_ascii
call put_char
; print DL lower nibble
mov al, dl
and al, 0Fh
call nibble_to_ascii
call put_char
ret
nibble_to_ascii:
cmp al, 0Ah
jl is_digit
add al, 'A' - 0Ah
ret
is_digit:
add al, '0'
ret
put_char:
mov ah, 0eh ; tty print character
int 10h
ret
register_buffer_ax:
dw 0
register_buffer_bx:
dw 0
register_buffer_cx:
dw 0
register_buffer_dx:
dw 0
register_buffer_si:
dw 0
register_buffer_di:
dw 0
register_buffer_bp:
dw 0
register_buffer_sp:
dw 0
register_buffer_cs:
dw 0
register_buffer_ds:
dw 0
register_buffer_es:
dw 0
register_buffer_ss:
dw 0
db 510-($-start) dup(0) ; padding
dw 0aa55h ; boot sector signature
code ends
end start