Сборка: [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. Вы должны использовать реестр в качестве посредника.