Как я могу отобразить секунды в загрузчике?

#assembly #operating-system #boot #fasm #bochs

#сборка #операционная система #загрузка #fasm #bochs

Вопрос:

Я работаю над образовательным проектом по написанию простого загрузчика на ассемблере. Что я использую:

  • fasm
  • bochs
  • скрипт для сборки
 fasm.exe boot.asm boot.bin
del disk.img
fsutil file createnew disk.img 1474560
dd if=boot.bin of=disk.img
 
  • команда для запуска boch
    bochs.exe -q -f bochsrc.bxrc

Мне нужно установить таймер секунд справа. После исследования мне нужно перехватить 0x08 прерывание и обработать его с помощью замены 0x1c , которая находится в конце 0x08 возврата iret по умолчанию.

При запуске программы я попытался заменить 0x1c в таблице векторов прерываний

 use16

org 0x7c00

boot__code16:
    offset_1ch equ 0x1c * 4
    
    cli
    xor ax,ax
    mov es, ax  
    mov es, ax
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov ax, boot__code16
    mov sp,ax

    mov ax, offset_1ch
    mov [es:offset_1ch], ax
    push cs
    pop ax
    mov [es:offset_1ch 2], ax
    
    sti
 

А затем отобразить что-то:

     mov ax, 0002h
    int 10h
    
    mov dx,0h
    call SetCursor
    
    mov bp, loading_str
    mov cx, 10
    call Print
 

Какая проблема у меня сейчас:
Если я заменю 0x1c , эмулятор ничего не отобразит.
Если я попытаюсь заменить другое прерывание (например, 0x1f), оно будет работать до тех пор, пока я не вызову его в коде, а затем оно ничего не отобразит.

Что я делаю не так?

UPD я изменил некоторый код:

     cli
    xor ax,ax
    mov es, ax  
    mov es, ax
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov ax, boot__code16
    mov sp,ax

    mov ax, timer
    mov [offset_1ch], ax
    sti
 
 timer:
    iret
 

Комментарии:

1. Не совсем понятно, что вы пытаетесь сделать. 1 / похоже, вы не соблюдаете структуру загрузочного сектора (в каком-то определенном месте есть данные и т. Д.) 2 / Вы заменяете вектор прерывания адресом cs: 70h, что вы ожидаете, что это будетделать, если по этому адресу нет кода? Для меня первый offset_1ch вход mov ax, offset_1ch mov [es:offset_1ch], ax выглядит как ошибка: он должен быть mov ax, offset_h , где offset_h находится адрес в сегменте cs вашего обработчика прерываний.

2. На самом деле это похоже на ошибку, я изменил код, но он не работает. Я добавлю свои изменения в вопрос

Ответ №1:

Я нашел решение. Это проще, чем я ожидал, мне нужно было только изменить память, используя сегмент и смещение.

     cli
    xor ax,ax
    mov es, ax  
    mov es, ax
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov ax, boot__code16
    mov sp,ax

    mov ax, timer
    mov [offset_1ch], ax
    mov [offset_1ch 2], es
    sti
 

Комментарии:

1. 1. Вам не нужно использовать mov es, ax трижды. 2. Вы можете использовать mov sp, boot__code16 без привлечения ax . 3. Вы должны установить sp сразу следующую инструкцию после той, которая устанавливает ss . 4. Как и 2, вы можете использовать напрямую mov word [offset_1ch], timer , не привлекая ax .

2. Хороший совет, я изменю свой код в соответствии с вашими комментариями