Остановка ОС при сравнении строк - PullRequest
1 голос
/ 11 июля 2019

Я пытаюсь создать операционную систему, я не знаю все на и на ассемблере, я в основном учусь на ходу. Вот проблема, я построил простую функцию для сравнения двух строк (eax и ebx), проблема в том, что когда я запускаю код, чтобы сделать это, моя система ничего не выполняет после вызова ... Что Я не так делаю?

compare:
    xor ecx, ecx
    .by_char:
        mov dh, [eax+ecx]
        mov dl, [ebx+ecx]
        cmp dh, dl
        inc ecx
        je .zero_test
        stc
        jmp .done
    .zero_test:
        cmp dh, 0
        je .done
        jmp .by_char
    .done:
        ret

Для справки вот код, из которого я вызываю эту функцию:

start:
    mov esp, stack
    mov si, msg_welcome
    call print

    mov eax, msg_welcome
    mov ebx, msg_diskerr
    call compare

    jc j_aa
    jmp j_bb 

    j_aa:
        mov si, msg_strnequ
        jmp part_b

    j_bb:
        mov si, msg_strrequ

    part_b:
        call print

        mov eax, msg_booting
        mov ebx, msg_booting
        call compare

        jc j_cc
        jmp j_dd

        j_cc:
            mov si, msg_strnequ
            jmp part_c

        j_dd:
            mov si, msg_strrequ

    part_c:
        call print
        jmp halt

halt:
    hlt
    jmp halt

Здесь я определяю свои переменные:

bss:
    msg_welcome: db "Welcome To Hypr Byte!", 10, 13, 10, 13, 0
    msg_nokernl: db "FATAL: Missing or Corrupted Kernel. System Halted...", 10, 13, 10, 13, 0
    msg_diskerr db "FATAL: An error occured while attempting to read the disk. Please go to https://www.instinct-loop.xyz/hypr/help to recieve support...", 0
    msg_bterror db "Uh oh! An error occured while attempting to boot. Please go to https://www.instinct-loop.xyz/hypr/help to recieve support...", 0
    msg_booting db "Attempting to load the kernel...", 10, 13, 10, 13, 0
    msg_kreturn db "Oops! The kernel ran into a fatal error... System Halted!", 0

    msg_strnequ db "Strings are Not Equal!", 10, 13, 0
    msg_strrequ db "Strings are Equal!", 10, 13, 0

1 Ответ

2 голосов
/ 11 июля 2019

моя ОС 16-битная, но когда я пытаюсь использовать 16-битные регистры в моей функции сравнения, она говорит мне, что я даю ей неверный эффективный адрес.

16-битные режимы адресации могут использовать только [bx|bp + si|di + constant] или его подмножество.Использование 32-битных режимов адресации является допустимым обходным решением, если вы не можете просто передать указатели в si и di для режимов адресации, таких как [si] и [di], как обычный человек.

Но только если вы расширите 16-битные адреса до нуля до полного 32-битного регистра , в противном случае большой мусор может привести к нарушению предела сегмента.В реальном режиме сегменты неявно имеют ограничение в 64 КБ;смещение> 65535 приведет к сбою.

Возможно, вы на самом деле не разбиваете сам VirtualBox, но вы можете разбить виртуальную гостевую машину с тройной ошибкой или чем-то еще.

mov eax, msg_welcome действительно пишетполный регистр с нулевым расширенным адресом, в отличие от mov si, msg_welcome


Ваш цикл всегда завершится после первой итерации, потому что inc ecx / je .zero_test проваливается.INC очищает ZF, потому что увеличение ECX от 0 до 1 оставляет ECX! = 0.

Предположительно, вам следует inc до cmp / je, если вы хотите, чтобы je читал флаги, установленные cmp.

Я не уверен, где ваш код на самом деле неисправен.Используйте для этого отладчик, например, запустив его внутри BOCHS вместо VirtualBox.BOCHS имеет встроенный отладчик, который понимает сегментацию, в отличие от подключения GDB к qemu или virtualbox в качестве GDB-пульта.


Ваш цикл довольно неэффективен, кстати.Вы можете использовать cmp dl, [di] или что-то еще и поставить jne внизу.Если вы выйдете из цикла с помощью cmp / jcc, вы можете поместить test dl,dl / jnz в качестве ветви цикла внизу.

Никогда не следует писать jcc вместо jmp, просто напишите JCC с противоположным условием, которое проваливается.И здесь вы можете провалиться на RET вместо jmp .done.(Единственное исключение - если вам нужно прыгнуть дальше, чем -128 .. + 127 байт, и вы нацелены на древний процессор, который не поддерживает JCC rel16, только короткий JCC rel8.)

НаПроцессор AMD (без частичного переименования регистров), mov dh, [mem] имеет ложную зависимость от mov dl, [mem], поэтому существует дополнительная задержка для объединения значений нагрузки до того, как ваш cmp сможет работать.Это еще одна причина использования cmp-with-mem вместо 2 загрузок.

...