[BITS 64] [ORG 0000000000200000h] %INCLUDE "bmdev.asm" start: ; Start of program label lea rax, [custom_interrupt_handler] ; Install new handler for RTC mov rcx, 28h lea rdx, [ORIGINAL_HANDLER] ; Save old handler address to ORIGINAL_HANDLER call install_interrupt_handler loop: xor rax, rax ; Check value of FLAG mov al, [FLAG] test al, al jz loop ; Loop while value is 0 mov byte [FLAG], 0 mov rsi, hello_message ; Load RSI with memory address of string call b_print_string ; Print the string that RSI points to mov rax, [ORIGINAL_HANDLER] ; Restore old handler mov rcx, 28h lea rdx, [ORIGINAL_HANDLER] call install_interrupt_handler ret ; Return to OS IDTR: times 10 db 0 ORIGINAL_HANDLER: times 8 db 0 ; Installs a new interrupt handler ; RCX interrupt ID (16 bit) ; RAX address of new handler ; RDX memory location to store address of old handler install_interrupt_handler: push rax ; Save rax push rbx ; Save rbx push rcx ; Save rcx cli ; Disable interrupts sidt [IDTR] ; Store value of IDTR to memory (2 + 8 bytes) lea rbx, [IDTR + 2] ; Select offset from IDTR mov rbx, [rbx] ; Read offset of IDT into RBX cmp rcx, 0FFFFh ; Skip installing handler if ID is out of range jge install_interrupt_handler cmp cx, word [IDTR] jge install_interrupt_handler shl rcx, 4 ; Address of IDT entry RCX (entry size is 16 bytes) lea rbx, [rbx + rcx] push rax ; Save the address of the new interrupt handler on the stack xor rax, rax ; Address of old interrupt handler mov eax, [rbx + 8] ; Load upper 32 bits of old interrupt handler from offset 8 shl rax, 32 mov ax, [rbx + 6] ; Load next 16 bits of old interrupt handler from offset 6 shl rax, 16 mov ax, [rbx] ; Load remaining 16 bits of old interrupt handler from offset 0 mov [rdx], rax ; Store address of old interrupt handler pop rax ; Address of new interrupt handler mov [rbx], ax ; Store lower 16 bits of new interrupt handler at offset 0 shr rax, 16 ; Store next 16 bits of new interrupt handler at offset 6 mov [rbx + 6], ax shr rax, 16 ; Store remaining 32 bits of new interrupt handler at offset 8 mov [rbx + 8], eax end_install_interrupt_handler: sti ; Enable interrupts pop rcx ; Restore rcx pop rbx ; Restore rbx pop rax ; Restore rax ret FLAG: db 0 hello_message: db 'Hello, world!', 13, 0 COUNT: db 0 custom_interrupt_handler: inc byte [COUNT] cmp byte [COUNT], 8 jne end_custom_interrupt_handler mov byte [FLAG], 1 end_custom_interrupt_handler: jmp [ORIGINAL_HANDLER]