Запись строки 16-разрядной сборки fasm

# #assembly #x86 #osdev #fasm #video-memory

Вопрос:

Я создал драйвер, который должен работать с vmem, но он не работает. Я думаю, что ошибка-это регистры, которые я использую для направления в память.

есть код водителя:

 ;;;;;;; Primary Video Driver
PVideo:
                .treadbyte:    ; in:eax=ID, [0 - 3440]; out:cl=BYTE [0 - 255]
                        push eax ebx
                        mov ebx, 0xb8000
                        imul eax, 2
                        inc eax
                        add ebx, eax
                        mov cl, byte[ebx]
                        pop eax ebx di
                        ret
                .treadattr:    ; in:eax=ID, [0 - 3440]; out:cl=BYTE [0 - 255]
                        push eax ebx
                        mov ebx, 0xb8000
                        imul eax, 2
                        add ebx, eax
                        mov cl, byte[ebx]
                        pop eax ebx
                        ret
                .twritebyte:   ; in:eax=ID, [0 - 3440]/dl=BYTE, [0 - 255]; out:none
                        push eax ebx
                        mov ebx, 0xb8000
                        imul eax, 2
                        inc ax
                        add ebx, eax
                        mov byte[ebx], dl
                        pop eax ebx
                        ret
                .twriteattr:   ; in:eax=ID, [0 - 3440]/dl=BYTE, [0 - 255]; out:none
                        push eax ebx
                        mov ebx, 0xb8000
                        imul eax, 2
                        add ebx, eax
                        mov byte[ebx], dl
                        pop eax ebx
                        ret
                .twritezs:     ; in:eax=POS, [0 - 3440-len(ZS)]/si=ZS, offset[0 - 32512]/dl=BYTE; out:none
                        push eax ebx
                        mov ebx, 0xb8000
                        ;imul eax, 2
                        ;inc eax
                        add ebx, eax
                    .l:
                        lodsb
                        cmp al, 0x00
                        je .ret
                        mov byte[ebx], dl
                        inc ebx
                        mov byte[ebx], al
                        inc ebx
                        jmp .l
                    .ret:
                        pop eax ebx
                        ret
 

Я анализирую код, но не могу найти ни одной ошибки.

P.S.: Я тестировал только функцию .twritezs, может быть, другая тоже не работает.

Ответ №1:

Это то, что неправильно в фрагментах кода:

  • Все, что вам push нужно в стеке, должно сниматься в обратном порядке (при использовании pop ).
  • В видеопамяти при 0x000B8000 код символа (ASCII) переходит в байт по четному адресу, а цветовой код (атрибут) переходит в байт по нечетному адресу.
     push eax ebx
    lea  ebx, [0x000B8000   eax]
    mov  ah, dl      ; Attribute
  .next:
    lodsb            ; ASCII
    cmp  al, 0
    je   .ret
    mov  [ebx], ax   ; Store ASCII at even address and Attribute at next odd address
    add  ebx, 2
    jmp  .next
  .ret:
    pop  ebx eax
    ret
 

Вы можете быстрее получить код .twritezs, если сохраните ASCII (по четному адресу) и Атрибут (по следующему нечетному адресу) вместе в одной инструкции.
Обратите внимание, что (E)SI это изменено. Ты push этого не делал.


Непонятно, почему вы хотите умножить на 2 значение EAX , указанное в других фрагментах кода. Разве EAX в видеобуфере уже нет готового к использованию смещения, как в коде .twritezs?