Сборка: [SI + CX] = невозможная комбинация размеров адресов

Итак, сегодня я попытался создать библиотеку для моей операционной системы с одной простой функцией: печатать символы на экране. Чтобы использовать эту функцию, мне просто нужно поместить адрес строки в стек и вызвать ее (строка должна заканчиваться байтом 0x00). Ниже приведен исходный код функции:

__print:                        ;Print string that is terminated with a 0x00 to screen

__print_prepare:
    pop si                  ;SI Register = String Address
    mov ah, 0x0E                ;0x0E Function = Print Character on screen
    mov bx, 0x0F                ;Background = Black, CharColor = White
    xor cx, cx              ;Counter = 0

__print_check:
    push byte [cx + si]         ;Push character to the stack
    or byte [cx + si], byte [cx + si]   ;Check if the byte equals 0x00
    jz __print_exit             ;If true then exit
    jmp __print_main            ;Else print the character

__print_main:
    pop al                  ;Store the byte in the AL Register
    int 0x10                ;Call interupt 0x10 = BIOS Interupt
    jmp __print_next            ;Continue to next character

__print_next:
    inc cx                  ;Increment CX Register by one for next character = Counter
    jmp __print_check           ;Check authenticity of character

__print_exit:
    ret

Каждый раз, когда я пытаюсь собрать исходный код, появляется следующая ошибка:

def_os_lib.asm: 10: ошибка: недопустимая комбинация кода операции и операндов

def_os_lib.asm:11: ошибка: недопустимая комбинация кода операции и операндов

def_os_lib.asm:16: ошибка: недопустимая комбинация кода операции и операндов

Кроме того, в некоторых случаях, то есть когда я компилирую его в формате ELF, он выдает следующую ошибку:

def_os_lib.asm: 10: ошибка: невозможно сочетание размеров адресов

def_os_lib.asm:11: ошибка: невозможно сочетание размеров адресов

Команда, которую я использую для nasm(bin):

nasm -f bin def_os_lib.asm

Команда, которую я использую для nasm(elf64):

nasm -f elf64 def_os_lib.asm

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

Спасибо за вашу помощь. Я дополнил исходный код, исправив ошибки с вашими предложениями. Вот новый код:

__print:                        ;Print string that is terminated with a 0x00 to screen

__print_prepare:
    pop si                  ;SI Register = String Address
    xor bx, bx              ;Counter = 0

__print_check:
    push bx                 ;Save BX
    xor ax, ax              ;AX = 0
    add bx, si              ;BX = Address of the character
    mov al, byte [bx]           ;AL = Character
    pop bx                  ;Restore BX
    push ax                 ;Save character
    or ax, ax               ;Check if the byte equals 0x00
    jz __print_exit             ;If true then exit
    jmp __print_main            ;Else print the character

__print_main:
    pop ax                  ;Store the byte in the AL Register
    push bx                 ;Save BX
    mov bx, 0x0F                ;Background = Black, CharColor = White
    mov ah, 0x0E                ;0x0E Function = Print Character on screen
    int 0x10                ;Call interupt 0x10 = BIOS Interupt
    jmp __print_next            ;Continue to next character

__print_next:
    pop bx                  ;Restore BX
    inc bx                  ;Increment CX Register by one for next character = Counter
    jmp __print_check           ;Check authenticity of character

__print_exit:
    ret

2 ответа

Решение

Вы можете использовать [BX или BP] только в сочетании с [SI или DI]; AX, DX или CX не допускаются.

Вы не можете PUSH/POP байт так POP AL поэтому любой аргумент размера байта будет считаться недействительным.

push byte [cx + si]

cx не может быть использован для адресации в реальном режиме.

или байт [cx + si], байт [cx + si]

Вы не можете иметь два операнда памяти в одной инструкции обычно в x86. Вы должны использовать реестр в качестве посредника.

Другие вопросы по тегам