Bob Dude
Bob Dude

Reputation: 41

Making an IDT in assembly

I know this is naive but I want my entire OS code written in assembly and that includes the IDT, but I don't recall there having ever been an IDT in assembly so I used objconv but it outputs some code that I think is for EXEs instead of binart/OS and I have been debugging this code. I cannot figure why it errors because of the 'special symbols' that are in isg, ieg, idg, imake, and I can't use BOCHS because I can't assemble the code.

The IDT code written in C can be found in Nanobytes tutorial and the full outputted ASM code is below.

The code:

bootloader:

[org 0x7C00]
[bits 16]

%define ENDL 0x0D, 0x0A

jmp short start
nop

bdb_oem:                    db 'CHOMPER.'
bdb_bytes_per_sector:       dw 512
bdb_sectors_per_cluster:    db 1
bdb_reserved_sectors:       dw 1
bdb_fat_count:              db 2
bdb_dir_entries_count:      dw 0E0h
bdb_total_sectors:          dw 2880
bdb_media_descriptor_type:  db 0F0h
bdb_sectors_per_fat:        dw 9
bdb_sectors_per_track:      dw 18
bdb_heads:                  dw 2
bdb_hidden_sectors:         dd 0
bdb_large_sector_count:     dd 0

ebr_drive_number:           db 0
                            db 0
ebr_signature:              db 29h
ebr_volume_id:              db 12h, 34h, 56h, 78h
ebr_volume_label:           db 'CHOMPER. OS'
ebr_system_id:              db 'FAT12   '

start:
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00
    push es
    push word .after
    retf

.after:
    mov [ebr_drive_number], dl
    mov si, msg_loading
    call puts
    push es
    mov ah, 08h
    int 13h
    jc floppy_error
    pop es
    and cl, 0x3F
    xor ch, ch
    mov [bdb_sectors_per_track], cx
    inc dh
    mov [bdb_heads], dh
    mov ax, [bdb_sectors_per_fat]
    mov bl, [bdb_fat_count]
    xor bh, bh
    mul bx
    add ax, [bdb_reserved_sectors]
    push ax
    mov ax, [bdb_dir_entries_count]
    shl ax, 5
    xor dx, dx
    div word [bdb_bytes_per_sector]
    test dx, dx
    jz .root_dir_after
    inc ax

.root_dir_after:
    mov cl, al
    pop ax
    mov dl, [ebr_drive_number]
    mov bx, buffer
    call disk_read
    xor bx, bx
    mov di, buffer

.search_kernal:
    mov si, file_kernal_bin
    mov cx, 11
    push di
    repe cmpsb
    pop di
    je .found_kernal
    add di, 32
    inc bx
    cmp bx, [bdb_dir_entries_count]
    jl .search_kernal
    jmp kernal_not_found_error

.found_kernal:
    mov ax, [di + 26]
    mov [kernal_cluster], ax
    mov ax, [bdb_reserved_sectors]
    mov bx, buffer
    mov cl, [bdb_sectors_per_fat]
    mov dl, [ebr_drive_number]
    call disk_read
    mov bx, kernal_LOAD_SEGMENT
    mov es, bx
    mov bx, kernal_LOAD_OFFSET

.load_kernal_loop:
    mov ax, [kernal_cluster]
    add ax, 31
    mov cl, 1
    mov dl, [ebr_drive_number]
    call disk_read
    add bx, [bdb_bytes_per_sector]
    mov ax, [kernal_cluster]
    mov cx, 3
    mul cx
    mov cx, 2
    div cx
    mov si, buffer
    add si, ax
    mov ax, [ds:si]
    or dx, dx
    jz .even

.odd:
    shr ax, 4
    jmp .next_cluster_after

.even:
    and ax, 0x0FFF

.next_cluster_after:
    cmp ax, 0x0FF8
    jae .read_finish
    mov [kernal_cluster], ax
    jmp .load_kernal_loop

.read_finish:
    mov dl, [ebr_drive_number]
    mov ax, kernal_LOAD_SEGMENT
    mov ds, ax
    mov es, ax
    jmp kernal_LOAD_SEGMENT:kernal_LOAD_OFFSET
    jmp wait_key_and_reboot
    cli
    hlt

floppy_error:
    mov si, msg_read_failed
    call puts
    jmp wait_key_and_reboot

kernal_not_found_error:
    mov si, msg_kernal_not_found
    call puts
    jmp wait_key_and_reboot

wait_key_and_reboot:
    xor ah, ah
    int 16h
    jmp 0FFFFh:0

.halt:
    cli
    hlt

puts:
    push si
    push ax
    push bx

.loop:
    lodsb
    or al, al
    jz .done
    mov ah, 0x0E
    xor bh, bh
    int 0x10
    jmp .loop

.done:
    pop bx
    pop ax
    pop si    
    ret

lba_to_chs:
    push ax
    push dx
    xor dx, dx
    div word [bdb_sectors_per_track]
    inc dx
    mov cx, dx
    xor dx, dx
    div word [bdb_heads]
    mov dh, dl
    mov ch, al
    shl ah, 6
    or cl, ah
    pop ax
    mov dl, al
    pop ax
    ret

disk_read:
    push ax
    push bx
    push cx
    push dx
    push di
    push cx
    call lba_to_chs
    pop ax
    mov ah, 02h
    mov di, 3

.retry:
    pusha
    stc
    int 13h
    jnc .done
    popa
    call disk_reset
    dec di
    test di, di
    jnz .retry

.fail:
    jmp floppy_error

.done:
    popa
    pop di
    pop dx
    pop cx
    pop bx
    pop ax
    ret

disk_reset:
    pusha
    xor ah, ah
    stc
    int 13h
    jc floppy_error
    popa
    ret

msg_loading:            db 'BOOT START', ENDL, 0
msg_read_failed:        db 'FAIL READ DISK', ENDL, 0
msg_kernal_not_found:   db 'KERNAL NOT FOUND', ENDL, 0
file_kernal_bin:        db 'KERNAL  BIN'
kernal_cluster:         dw 0

kernal_LOAD_SEGMENT     equ 0x0000
kernal_LOAD_OFFSET      equ 0x8000

times 510-($-$$) db 0
dw 0AA55h

`buffer`:

kernal(ignore drawing code as it was from a MASM project and I just put some 32-bit things inside it for 'testing'):

[org 0x8000]
[bits 16]

jmp short start

gdt_start:
    dq 0x0000000000000000

    dq 0x00CF9A000000FFFF
    dq 0x00CF92000000FFFF

    dq 0x00CF92000000FFFF

gdt_end:

gdt_descriptor:
    dw gdt_end - gdt_start - 1
    dd gdt_start

print:
    push si
    push ax
    push bx

.loop:
    lodsb
    or al, al
    jz .done

    mov ah, 0x0E
    mov bh, 0
    int 0x10

    jmp .loop

.done:
    pop bx
    pop ax
    pop si    
    ret

start:
    mov si, start_sixteen
    call print
    
    in al, 0x64
.wait_ibe:
    test al, 0x02
    jnz .wait_ibe
    mov al, 0xD1
    out 0x64, al
.wait_ibe2:
    in al, 0x64
    test al, 0x02
    jnz .wait_ibe2
    mov al, 0xDF
    out 0x60, al

first_sixteen:
    cli
    lgdt [gdt_descriptor]

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp dword 0x08:.afterstart

[bits 32]

.afterstart:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

global isg: function
global ieg: function
global idg: function
global imake: function
global IDTDescriptor

extern IDTLoad
extern IDT

    jmp short isg

global i686IDTLoad

i686IDTLoad:
    push ebp
    mov ebp, esp

    mov eax, [ebp + 8]
    lidt [eax]

    mov esp, ebp
    pop ebp
    ret

section .idt align=4

isg:
        push    ebp
        mov     ebp, esp
        sub     esp, 8
        mov     edx, dword [ebp+10H]
        mov     eax, dword [ebp+14H]
        mov     word [ebp-4H], dx
        mov     byte [ebp-8H], al
        mov     eax, dword [ebp+0CH]
        mov     edx, eax
        mov     eax, dword [ebp+8H]
        mov     word [IDT+eax*8], dx
        mov     eax, dword [ebp+8H]
        movzx   edx, word [ebp-4H]
        mov     word [IDT+2H+eax*8], dx
        mov     eax, dword [ebp+8H]
        mov     byte [IDT+4H+eax*8], 0
        mov     eax, dword [ebp+8H]
        movzx   edx, byte [ebp-8H]
        mov     byte [IDT+5H+eax*8], dl
        mov     eax, dword [ebp+0CH]
        shr     eax, 16
        mov     edx, eax
        mov     eax, dword [ebp+8H]
        mov     word [IDT+6H+eax*8], dx
        nop
        leave
        ret

ieg:
        push    ebp
        mov     ebp, esp
        mov     eax, dword [ebp+8H]
        movzx   eax, byte [IDT+5H+eax*8]
        or      eax, 0FFFFFF80H
        mov     edx, eax
        mov     eax, dword [ebp+8H]
        mov     byte [IDT+5H+eax*8], dl
        nop
        pop     ebp
        ret

idg:
        push    ebp
        mov     ebp, esp
        mov     eax, dword [ebp+8H]
        movzx   eax, byte [IDT+5H+eax*8]
        and     eax, 7FH
        mov     edx, eax
        mov     eax, dword [ebp+8H]
        mov     byte [IDT+5H+eax*8], dl
        nop
        pop     ebp
        ret

imake:
        push    ebp
        mov     ebp, esp
        sub     esp, 24
        mov     dword [esp], IDTDescriptor
        call    i686IDTLoad
        nop
        leave
        ret

        nop
        nop

IDTDescriptor:
        db 0FFH, 07H, 00H, 00H
        dd IDT

SECTION .drectve align=4
    db 20H, 2DH, 61H, 6CH, 69H, 67H, 6EH, 63H
    db 6FH, 6DH, 6DH, 3AH, 22H, 5FH, 67H, 5FH
    db 49H, 44H, 54H, 22H, 2CH, 35H, 00H, 00H

SECTION .rdata$zzz align=4
    db 47H, 43H, 43H, 3AH, 20H, 28H, 4DH, 69H
    db 6EH, 47H, 57H, 2EH, 6FH, 72H, 67H, 20H
    db 47H, 43H, 43H, 2DH, 36H, 2EH, 33H, 2EH
    db 30H, 2DH, 31H, 29H, 20H, 36H, 2EH, 33H
    db 2EH, 30H, 00H, 00H

    cli
    hlt

start_prog:
    mov al, 2
    mov ax, 1004
    mov [Xval], eax
    mov ax, 700
    mov [Yval], eax
    mov ax, 10
    mov [Wval], eax
    mov ax, 20
    mov [Hval], eax
    lea si, [PySpr]
    
    call draw_spr

.halt:
    cli
    hlt

draw_spr:
    xor edx, edx
    mov ecx, [Hval]
draw_sprite:
    mov eax, [Yval]
    mov ebx, 1024
    mul ebx
    add eax, [Xval]
    add edi, eax
    push ecx
    mov ecx, [Wval]
draw_pixels:
    mov al, [si]
    cmp al, 5
    je skip_pixel_2
    cld
    movsb
    jmp skip_pixel
skip_pixel_2:
    inc edi
skip_pixel:
    inc si
    loop draw_pixels
    pop ecx
    mov eax, [Yval]
    inc eax
    mov [Yval], eax
    loop draw_sprite
    ret

start_sixteen: db 'KERNAL START', 0x0D, 0x0A, 0

Xval dd 0
Yval dd 0
Wval dd 0
Hval dw 0

PySpr db 5,5,5,2,2,2,2,5,5,5
      db 5,5,2,2,2,2,2,2,5,5
      db 5,2,2,2,2,2,2,2,2,5
      db 2,2,2,2,2,2,2,2,2,2
      db 5,8,8,8,8,8,8,8,8,5
      db 5,8,15,0,8,8,0,15,8,5
      db 5,8,8,8,8,8,8,8,8,5
      db 5,8,8,0,0,0,0,8,8,5
      db 5,5,8,8,8,8,8,8,5,5
      db 2,2,2,2,2,2,2,2,2,2
      db 2,2,2,2,2,2,2,2,2,2
      db 2,5,2,2,2,2,2,2,5,2
      db 2,5,2,2,2,2,2,2,5,2
      db 2,5,2,2,2,2,2,2,5,2
      db 8,5,2,2,2,2,2,2,5,8
      db 5,5,6,6,6,6,6,6,5,5
      db 5,5,6,6,5,5,6,6,5,5
      db 5,5,6,6,5,5,6,6,5,5
      db 5,5,6,6,5,5,6,6,5,5
      db 5,7,7,7,5,5,7,7,7,5

Assembly output of idt.o:

; Disassembly of file: idt.o
; Sat Dec 28 09:27:06 2024
; Type: COFF32
; Syntax: NASM
; Instruction set: 80386


global _i686_isg: function
global _i686_IDT_EnableGate: function
global _i686_IDT_DisableGate: function
global _i686_IDT_Initialize: function
global IDTDescriptor

extern _i686_IDT_Load                                   ; near
extern IDT                                           ; word


SECTION .text   align=4 exec                            ; section number 1, code

.text:  ; Local function

_i686_isg:
        push    ebp                                     ; 0000 _ 55
        mov     ebp, esp                                ; 0001 _ 89. E5
        sub     esp, 8                                  ; 0003 _ 83. EC, 08
        mov     edx, dword [ebp+10H]                    ; 0006 _ 8B. 55, 10
        mov     eax, dword [ebp+14H]                    ; 0009 _ 8B. 45, 14
        mov     word [ebp-4H], dx                       ; 000C _ 66: 89. 55, FC
        mov     byte [ebp-8H], al                       ; 0010 _ 88. 45, F8
        mov     eax, dword [ebp+0CH]                    ; 0013 _ 8B. 45, 0C
        mov     edx, eax                                ; 0016 _ 89. C2
        mov     eax, dword [ebp+8H]                     ; 0018 _ 8B. 45, 08
        mov     word [IDT+eax*8], dx                 ; 001B _ 66: 89. 14 C5, 00000000(d)
        mov     eax, dword [ebp+8H]                     ; 0023 _ 8B. 45, 08
        movzx   edx, word [ebp-4H]                      ; 0026 _ 0F B7. 55, FC
        mov     word [IDT+2H+eax*8], dx              ; 002A _ 66: 89. 14 C5, 00000002(d)
        mov     eax, dword [ebp+8H]                     ; 0032 _ 8B. 45, 08
        mov     byte [IDT+4H+eax*8], 0               ; 0035 _ C6. 04 C5, 00000004(d), 00
        mov     eax, dword [ebp+8H]                     ; 003D _ 8B. 45, 08
        movzx   edx, byte [ebp-8H]                      ; 0040 _ 0F B6. 55, F8
        mov     byte [IDT+5H+eax*8], dl              ; 0044 _ 88. 14 C5, 00000005(d)
        mov     eax, dword [ebp+0CH]                    ; 004B _ 8B. 45, 0C
        shr     eax, 16                                 ; 004E _ C1. E8, 10
        mov     edx, eax                                ; 0051 _ 89. C2
        mov     eax, dword [ebp+8H]                     ; 0053 _ 8B. 45, 08
        mov     word [IDT+6H+eax*8], dx              ; 0056 _ 66: 89. 14 C5, 00000006(d)
        nop                                             ; 005E _ 90
        leave                                           ; 005F _ C9
        ret                                             ; 0060 _ C3

_i686_IDT_EnableGate:; Function begin
        push    ebp                                     ; 0061 _ 55
        mov     ebp, esp                                ; 0062 _ 89. E5
        mov     eax, dword [ebp+8H]                     ; 0064 _ 8B. 45, 08
        movzx   eax, byte [IDT+5H+eax*8]             ; 0067 _ 0F B6. 04 C5, 00000005(d)
        or      eax, 0FFFFFF80H                         ; 006F _ 83. C8, 80
        mov     edx, eax                                ; 0072 _ 89. C2
        mov     eax, dword [ebp+8H]                     ; 0074 _ 8B. 45, 08
        mov     byte [IDT+5H+eax*8], dl              ; 0077 _ 88. 14 C5, 00000005(d)
        nop                                             ; 007E _ 90
        pop     ebp                                     ; 007F _ 5D
        ret                                             ; 0080 _ C3
; _i686_IDT_EnableGate End of function

_i686_IDT_DisableGate:; Function begin
        push    ebp                                     ; 0081 _ 55
        mov     ebp, esp                                ; 0082 _ 89. E5
        mov     eax, dword [ebp+8H]                     ; 0084 _ 8B. 45, 08
        movzx   eax, byte [IDT+5H+eax*8]             ; 0087 _ 0F B6. 04 C5, 00000005(d)
        and     eax, 7FH                                ; 008F _ 83. E0, 7F
        mov     edx, eax                                ; 0092 _ 89. C2
        mov     eax, dword [ebp+8H]                     ; 0094 _ 8B. 45, 08
        mov     byte [IDT+5H+eax*8], dl              ; 0097 _ 88. 14 C5, 00000005(d)
        nop                                             ; 009E _ 90
        pop     ebp                                     ; 009F _ 5D
        ret                                             ; 00A0 _ C3
; _i686_IDT_DisableGate End of function

_i686_IDT_Initialize:; Function begin
        push    ebp                                     ; 00A1 _ 55
        mov     ebp, esp                                ; 00A2 _ 89. E5
        sub     esp, 24                                 ; 00A4 _ 83. EC, 18
        mov     dword [esp], IDTDescriptor           ; 00A7 _ C7. 04 24, 00000000(d)
        call    _i686_IDT_Load                          ; 00AE _ E8, 00000000(rel)
        nop                                             ; 00B3 _ 90
        leave                                           ; 00B4 _ C9
        ret                                             ; 00B5 _ C3
; _i686_IDT_Initialize End of function

        nop                                             ; 00B6 _ 90
        nop                                             ; 00B7 _ 90


SECTION .data   align=4 noexec                          ; section number 2, data

IDTDescriptor:                                       ; byte
        db 0FFH, 07H, 00H, 00H                          ; 0000 _ ....
        dd IDT                                       ; 0004 _ 00000000 (d)


SECTION .bss    align=4 noexec                          ; section number 3, bss


SECTION .drectve align=4 noexec                         ; section number 4, data

        db 20H, 2DH, 61H, 6CH, 69H, 67H, 6EH, 63H       ; 0000 _  -alignc
        db 6FH, 6DH, 6DH, 3AH, 22H, 5FH, 67H, 5FH       ; 0008 _ omm:"
        db 49H, 44H, 54H, 22H, 2CH, 35H, 00H, 00H       ; 0010 _ IDT",5..


SECTION .rdata$zzz align=4 noexec                       ; section number 5, const

        db 47H, 43H, 43H, 3AH, 20H, 28H, 4DH, 69H       ; 0000 _ GCC: (Mi
        db 6EH, 47H, 57H, 2EH, 6FH, 72H, 67H, 20H       ; 0008 _ nGW.org 
        db 47H, 43H, 43H, 2DH, 36H, 2EH, 33H, 2EH       ; 0010 _ GCC-6.3.
        db 30H, 2DH, 31H, 29H, 20H, 36H, 2EH, 33H       ; 0018 _ 0-1) 6.3
        db 2EH, 30H, 00H, 00H                           ; 0020 _ .0..

Build commands:

nasm scr/boot.asm -f bin -o build/boot.bin
nasm scr/kernal.asm -f bin -o build/kernal.bin
dd if=/dev/zero of=v_005.img bs=512 count=2880
mkfs.fat -F 12 -n NBOS v_005.img
dd if=boot.bin of=v_005.img conv=notrunc
mcopy -i v_005.img kernal.bin ::kernal.bin

Upvotes: 2

Views: 113

Answers (0)

Related Questions