GNU Assembler BIOS Interrupt Handler

I write a loader in Assembly language (GNU Assembler, syntax AT&T). You need to write an interrupt handler for it BIOS.

On the Internet, I found that in order to make my "function" a handler, you need to call the subfunction 0x25 of the interrupt 0x21, specifying in the register al the desired number for your interrupt, in the register ds - a segment, in the register dx - a shift to your function relative to this segment.

Let them eat program:

.code16
.text
.globl _start

_start:
    jmp _boot

.macro mWriteString str
    leaw  \str, %si
    call   WriteString
.endm

.func WriteString
WriteString:
    lodsb
    orb     %al, %al
    jz     WriteString_done

    movb    $0xe, %ah
    movw    $9, %bx
    int    $0x10

    jmp    WriteString

    WriteString_done:
    retw
.endfunc

msgHello: .asciz "Hello in my boot loader!\n\r"

myInterrupt:
    mWriteString msgHello
    iret

_boot:
    cli
    movw $0x07C0, %ax
    movw %ax, %ds
    movw %ax, %ss
    movw %ax, %sp
    sti

    mov $0x25, %ah
    mov $0x65, %al
    mov myInterrupt, %dx
    int $0x21

    int $0x65

    . = _start + 510
    .byte 0x55
    .byte 0xAA

When interrupted, a line with the text "Hello in my boot loader!"should be displayed on the screen. But, unfortunately, this line is not output, from where I conclude that the interrupt is not called.

I ask for help in bringing the code to a working state!

Author: AccumPlus, 2017-05-15

1 answers

I have achieved positive results. Special thanks to Mike for a very useful link. Here's what happened:

.code16
.text
.globl _start

_start:
    jmp _boot

.macro mWriteString str
    leaw  \str, %si
    call   WriteString
.endm

.func WriteString
WriteString:
    lodsb
    orb %al, %al
    jz WriteString_done

    movb $0xe, %ah
    movw $9, %bx
    int $0x10

    jmp WriteString

    WriteString_done:
    retw
.endfunc

msgHello: .asciz "Hello in my boot loader!\n\r"

myInterrupt:
    mWriteString msgHello
    hlt

// Смещение вектора 0x65
.set off_x65, 0x65*4
old_off_x65: .long 0
old_seg_x65: .long 0

_boot:
    cli

    movw $0x07C0, %ax
    movw %ax, %ds
    movw %ax, %ss
    movw %ax, %sp

    movw $0x0, %ax
    movw %ax, %es

    // Сохраняем старый вектор
    movw %es:off_x65, %ax
    movw %ax, old_off_x65
    movw %es:off_x65 + 2, %ax
    movw %ax, old_seg_x65

    // Записываем новый вектор
    movw $myInterrupt, %ax
    movw %ax, %es:off_x65
    push %ds
    pop %ax
    movw %ax, %es:off_x65+2

    sti

    int $0x65

    . = _start + 510
    .byte 0x55
    .byte 0xAA
 2
Author: AccumPlus, 2017-05-17 10:35:46