команда ver и команда reboot. Ver - выводит текст на экран. reboot - перезагружает процессор. Но есть проблема. когда я начинаю вводить символ r, то следуйщие символы с функции check_for_reboot не выводяться, но когда я заканчиваю ввод символов которые не выводяться, команда перезагрузки выполняеться.
Вот сам код функции:
check_for_reboot:
; Перевірка наступних символів для команди "reboot"
mov ah, 0
int 16h
cmp al, 'e'
jne input_loop
mov ah, 0
int 16h
cmp al, 'b'
jne input_loop
mov ah, 0
int 16h
cmp al, 'o'
jne input_loop
mov ah, 0
int 16h
cmp al, 'o'
jne input_loop
mov ah, 0
int 16h
cmp al, 't'
jne input_loop
jmp reboot
Но, если я ввожу ver - все символы выводяться, хоть структура такая же:
check_for_ver:
; Перевірка наступних символів для команди "version"
mov ah, 0
int 16h
cmp al, 'e'
jne input_loop
mov ah, 0
int 16h
cmp al, 'r'
jne input_loop
; Виведення інформації про версію
mov si, version_info
call print_string
jmp input_loop
Весь код:
; Created on 18.08.2023
[bits 16]
[org 0x7c00]
start:
xor ax, ax
mov ds, ax
mov es, ax
; Виведення привітання
mov si, hello
call print_string
; Очікування введення
mov ah, 00h
int 16h
input_loop:
; Очікування введення символу
mov ah, 0
int 16h
; Перевірка на Enter
cmp al, 0x0D
je new_line
; Виведення символу
mov bl, al
call print_char
; Перевірка на команду "version"
cmp al, 'v'
je check_for_ver
; Перевірка на команду "reboot"
cmp al, 'r'
je check_for_reboot
; Повернення до циклу вводу
jmp input_loop
check_for_ver:
; Перевірка наступних символів для команди "version"
mov ah, 0
int 16h
cmp al, 'e'
jne input_loop
mov ah, 0
int 16h
cmp al, 'r'
jne input_loop
; Виведення інформації про версію
mov si, version_info
call print_string
jmp input_loop
new_line:
; Виведення нового рядка
call print_new_line
mov bl, 0x0D
call print_char
mov bl, 0x0A
call print_char
jmp input_loop
check_for_reboot:
; Перевірка наступних символів для команди "reboot"
mov ah, 0
int 16h
cmp al, 'e'
jne input_loop
mov ah, 0
int 16h
cmp al, 'b'
jne input_loop
mov ah, 0
int 16h
cmp al, 'o'
jne input_loop
mov ah, 0
int 16h
cmp al, 'o'
jne input_loop
mov ah, 0
int 16h
cmp al, 't'
jne input_loop
; Якщо всі символи правильні, перезавантаження
jmp reboot
print_string:
mov ah, 0x0E
.repeat_next_char:
lodsb
cmp al, 0
je .done_print
int 0x10
jmp .repeat_next_char
.done_print:
ret
print_char:
mov ah, 0x0E
mov al, bl
int 0x10
ret
print_new_line:
mov ah, 0x0E
mov al, 0x0A
int 0x10
ret
move_cursor_left:
mov ah, 02h
mov bh, 0
dec dl
int 10h
ret
reboot:
mov al, 0xFE ; Записуємо команду 0xFE до AL (команда перезавантаження)
out 0x64, al ; Відправляємо команду до порту 0x64 (контролер клавіатури для 8042)
hlt ; Зупиняємо виконання (halt) процесора
hello db 'Test 0.1',0x0A, 0x0D, 0
version_info db 'Version: 0.1',0x0A, 0x0D, 0
times 510 - ($-$$) db 0x00
dw 0xAA55
сама проверка символов начинаеться в функции input_loop. Как можно починить проблему с выводом символов?
Символы не выводятся, потому что ты их не выводишь при сравнении с текстом команды. Для обеих команд. А в главном цикле выводятся. Т.е., когда у тебя «рассинхронизация» и ты в главном цикле вводишь что-то помимо r и v, ты видишь текст. Кроме того, у тебя лишний int 16h ещё до главного цикла, он проглатывает первый символ после ребута. Сделай input_char хотя бы. Или нормальный буфер под команду и сравнение/выполнение по нажатию Enter.
Я попробовал переписать много чего совсем по другому. Урал лишний int 16h, попробовал буфер сделать, добавил попытку реализацию через ентер но теперь ни одна команда не работает, а что либо я не напишу и нажму на ентер - выводиться сообщение как команда version распозналась. Код на ~150 строчку, так что не захламлять чат пихнул на pastebin: https://pastebin.com/Vktivtgy Я попробовал реализовать отладку и выходит что либо я напишу и нажму на ентер - распознается что это команда ver. Выходит проблема в распознавание символов, но у меня нет идей что может быть не так. За сравнение строк отвечает три функции compare_strings: ; Сравнение двух строк push si push di .compare_loop: lodsb scasb jne not_equal cmp al, 0 jne .compare_loop pop di pop si mov al, 1 ret not_equal: pop di pop si xor al, al ret Если кратко. Не подскажешь и на этот раз в чём может быть загвоздка?
1) mov si, input_index вот это должно быть в квадратных скобках, тут доступ к памяти по адресу, а не загрузка самого адреса (и придётся movzx или сделать индекс 16-битным). И остальное проверь. 2)xor byte [input_index], 0 не будет работать, ксор с нулём не меняет значение. 3) compare_strings возвращает результат в al, а ты после вызова проверяешь ZF, который при любом исходе будет поднят, поэтому оно и идёт в версию.
Благодарю. Всё работает
Перезагружает процессор?
Трижды перегружает?
Можно поподробней?
Говорят, что надо 3 перегружать
reboot_system: mov al, 0xFE out 0x64, al jmp $ mov al, 0xFE out 0x64, al jmp $ mov al, 0xFE out 0x64, al hlt
Обсуждают сегодня