OS(7) ソフトウェア割り込みを発生させてみる
ISRとIDTが作成できたので、ソフトウェア割り込みが実行されることを確認する。
ipl.asmの修正
kernel.binが大きくなってきたので、ロードサイズを2から16へ増やす。変更部分は次の箇所。
mov ax, 0x0210 ; 16セクタ読み出し
kernel.asmの修正
変更内容は
- 文字列表示ルーチンの変更
- 呼ばれるたびに次の行から表示
- 最下行まで表示したら最上行へ。ただし画面は消さない
- IDT/ISRの作成
- IDTで発生した割り込み番号を画面に表示
といったところ。
; ; kernel.asm ; %include "defs.inc" [bits 32] [org PROG_START] ;------------------------------------------------------------------------ PROETCT_start: mov ax, DSEG mov ds, ax mov es, ax mov ss, ax mov esp, 0xa0000 ; メモリホール直前からスタック xor ax, ax mov fs, ax mov gs, ax mov esi, msg mov ah, 0x1f call puts lidt [IDTR] ; IDTを設定 int 0 ; ソフトウェア割り込み実行 int 0x40 int 0x80 int 0xff jmp $ msg: db 'This is PROTECTED mode kernel', 0 ;------------------------------------------------------------------------ ; 文字列表示 puts: push edi push eax mov eax, 80 * 2 mul byte [.@y] add eax, VRAM_OFS mov edi, eax pop eax push eax .@loop: lodsb stosw or al, al jnz .@loop inc byte [.@y] ; 表示の都度次の行へ cmp byte [.@y], 80 jb .@ret mov byte [.@y], 0 .@ret: pop eax pop edi ret .@y db 0 ; 次に表示する行 ;------------------------------------------------------------------------ IDTR: dw initial_IDT_end - initial_IDT - 1 dd initial_IDT ;------------------------------------------------------------------------ ; 割り込み番号の表示 show_number: cld mov edx, eax mov ax, DSEG mov ds, ax mov es, ax mov eax, edx shr al, 4 and al, 0xf add al, '0' cmp al, '9' jbe .@next add al, 'A' - ('9' + 1) .@next: mov [msg_int_num], al mov eax, edx and al, 0xf add al, '0' cmp al, '9' jbe .@next2 add al, 'A' - ('9' + 1) .@next2: mov [msg_int_num + 1], al mov esi, msg_int mov ah, 0x1c call puts ret msg_int: db 'INT ' msg_int_num: db ' ', 0 ;------------------------------------------------------------------------ ; ISR作成マクロ %macro make_ISR 1 ISR_%1: pusha push ds push es mov eax, %1 call show_number pop es pop ds popa iret %endmacro ; ISR作成 %assign n 0 %rep 256 make_ISR n %assign n n + 1 %endrep ;------------------------------------------------------------------------ ; IDT作成マクロ %macro make_IDT 1 %assign ofs (ISR_%1 - $$ + PROG_START) dw ofs & 0xffff dw CSEG db 0x0, 0x8e dw (ofs >> 16) & 0xffff %endmacro ; IDT作成 initial_IDT: %assign n 0 %rep 256 make_IDT n %assign n n + 1 %endrep initial_IDT_end:
defs.incの修正
CSEG equ 0x10 DSEG equ 0x18 VRAM_OFS equ 0xb8000 PROG_START equ 0x10200