目的
以下のIBMBIOSで実装されている文字列表示関数を追いました。
;--------------------------------------------
; THIS SUBROUTINE WILL PRINT A MESSAGE ON THE DISPLAY
;
;ENTRY REQUIREMENTS:
; SI = OFFSET (ADDRESS) OF MESSAGE BUFFER
; CX = MESSAGE BYTE COUNT
; MAXIMUM MESSAGE LENGTH IS 36 CHARACTERS
;--------------------------------------------
P_MSG PROC NEAR
MOV AX,DATA ;POINT DS TO DATA SEG
MOV DS,AX
CMP MFG_TST,1 ;MFG TEST MODE?
JNE G12 ;NO - DISPLAY ERROR MSG
MOV DH,1 ;YES - SETUP TO BEEP SPEAKER
JMP ERR_BEEP ;YES - BEEP SPEAKER
G12: ; WRITE_MSG:
MOV AL,CS:[SI] ;PUT CHAR IN AL
INC SI ; POINT TO NEXT CHAR
MOV BH,0 ;SET PAGE # TO ZERO
MOV AH,14 ;WRITE CHAR (TTY-INTERFACE)
INT 10H ;CALL VIDEO_IO
LOOP G12 ;CONTINUE TILL MSG WRITTEN
MOV AX,0E0DH ;POSITION CURSOR TO NEXT LINE
INT 10H ;SEND CARRIAGE RETURN AND
MOV AX,0E0AH ;LINE FEED CHARS
INT 10H
RET
P_MSG ENDP
NASM用に修正したコード
製造テストモード(工場検査中?)の場合はビープ音だけ鳴らして表示はしません。
今回自分で実装するに当たり製造モード判定のコードは省きます。
boot.asm
[org 0x7C00]
bits 16
start:
mov si, msg ; SI = 文字列のアドレス
mov cx, msg_len ; CX = 文字数
call g12
hlt_loop:
cli
hlt
loop hlt_loop
g12:
mov al,cs:[si]
inc si
mov bh, 0
mov ah,14 ; AH=0x0E 1文字
int 0x10
loop g12
mov ax, 0x0e0d ; CR
int 0x10
mov ax, 0x0e0a ; LF
int 0x10
ret
msg db 'Hello, World!'
msg_len equ $ - msg
times 510-($-$$) db 0
dw 0xAA55
検証
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
lsblk
sudo dd if=boot.bin of=/dev/sdb bs=512 count=2 conv=notrunc