Я работаю над программой DFA в Ассамблее. По сути, это система, которая читает двоичную строку и интерпретирует ее в следующих состояниях, показанных на изображении ниже.

По сути, он просто показывает четное количество нулей и четное количество единиц в строке. Я попытался представить эту систему с помощью следующей программы на ассемблере:
.section .data входная_подсказка: asciz "Введите строку из 0 и 1: " неверное_сообщение: .asciz "ОШИБКА: неверный ввод\n" EEPПодсказка: .asciz "Ввод принят\n" ПримечаниеEEПодсказка: .asciz "Ввод отклонен\n" новая линия: .байт 10 .раздел .bss вход: .байт 0 .byte 0 # для сохранения текущего символа .раздел .текст .globl основной основной: # ПЕЧАТАТЬ ПОДСКАЗКУ ВВОДА movl $4, %eax # Запись системного вызова movl $1, %ebx # stdout, подготовка к выводу lea input_prompt, %ecx # указывает на приглашение для ввода movl $29, %edx # загрузить длину нашего сообщения int $0x80 # вызвать системный вызов movl $0, %ebx # Инициализируем наше состояние lea input, %esi # указывает на входной буфер чтение_цикла: # Прочитайте каждый символ с помощью вызова getchar@PLT позвоните в getchar@PLT # ПРОВЕРКА НОВОЙ СТРОКИ cmpb $0x0A, %al #Если обнаружена новая строка, мы закончили. je input_complete # Завершить цикл # Нам нужно определить, является ли обрабатываемый символ «1» или «0». cmpb $0x30, %al # Сравнивает ввод с ASCII '0' jlvalid_input # Если оно меньше 0, ввод недействителен je Zero_entered # Если символ равен 0, перейти к таблице перехода cmpb $0x31, %al # Сравнить ввод с ASCII '1' jgvalid_input # Если введенное значение больше 1, введенное значение недействительно je one_entered # Если символ равен 1, перейти к таблице перехода # Сохраняем наш новый и действительный ввод movb %al, (%esi) # Сохранение символа inc %esi # Увеличение буфера ноль_введен: # '0' было введено cmpl $0, %eax # Мы находимся в EE. Теперь идем в ОЕ. je ee_to_oe cmpl $1, %eax # Мы находимся в оригинальном языке. Теперь идите в EE. я oe_to_ee cmpl $2, %eax # Мы в ОО. Перейти в ЭО я оо_то_ео cmpl $3, %eax # Мы находимся в EO. Идите в ОО. я eo_to_oo jmp read_loop one_entered: # '1' было введено cmpl $0, %eax # Мы находимся в EE. Теперь идем в ЭО je ee_to_eo cmpl $1, %eax # Мы находимся в оригинальном языке. Теперь идите в ОО. я oe_to_oo cmpl $2, %eax # Мы в ОО. Теперь идем в ОЕ. я оо_то_ое cmpl $3, %eax # Мы находимся в EO. Теперь идите в EE. я eo_to_ee jmp read_loop ee_to_oe: movl $1, %eax # EE в OE jmp read_loop oe_to_ee: movl $0, %eax # OE в EE jmp read_loop оо_то_ео: movl $3, %eax # OO в EO jmp read_loop eo_to_oo: movl $2, %eax # от EO до OO jmp read_loop ee_to_eo: movl $3, %eax # EE в EO jmp read_loop oe_to_oo: movl $2, %eax # от OE до OO jmp read_loop оо_то_ое: movl $1, %eax # OO в OE jmp read_loop eo_to_ee: movl $0, %eax # EO в EE jmp read_loop Неверный Ввод: # Обнаружен неверный ввод. Завершить программу. movl $4, %eax # системный вызов для записи movl $1, %ebx # стандартный вывод leavalid_message, %ecx# указывает на наше сообщение о недействительности movl $29, %edx # длина нашего сообщения int $0x80 # вызвать системный вызов # Выход с кодом состояния 1 movl $1, %eax # системный вызов для выхода xor %ebx, %ebx # код состояния: 1 int $0x80 # вызвать системный вызов принятый_вход: # Распечатать сообщение для ввода ПРИНЯТО movl $4, %eax # системный вызов для записи movl $1, %ebx # стандартный вывод lea EEPrompt, %ecx # указывает на наше сообщение о принятии movl $16, %edx # длина нашего сообщения int $0x80 # вызвать системный вызов # Выход с кодом состояния 1 movl $1, %eax # системный вызов для выхода xor %ebx, %ebx # код состояния: 1 int $0x80 # вызвать системный вызов отклоненный_вход: # Распечатать сообщение для ввода ОТКЛОНЕНО movl $4, %eax # системный вызов для записи movl $1, %ebx # стандартный вывод lea NotEEPrompt, %ecx # указать на сообщение об ошибке movl $16, %edx # длина сообщения int $0x80 # вызвать системный вызов # Выход с кодом состояния 1 movl $1, %eax # системный вызов: выход xor %ebx, %ebx # код состояния: 1 int $0x80 # вызвать системный вызов ввод_завершен: # Добавляем символ новой строки в конец ввода movb $0x0A, (%esi) # Теперь сравните значение %eax, чтобы увидеть, находимся ли мы в EE. Если 0 находится в %eax, мы находимся в EE. cmpl $0, %eax # Проверяем, находимся ли мы в EE. je Accepted_input # ЕСЛИ ДА, распечатываем принятое сообщение и выходим jg ignore_input # ЕСЛИ НЕТ, распечатываем наше отклоненное сообщение и выходим #Выходим из программы movl $1, %eax # системный вызов: выход xor %ebx, %ebx # код состояния: 0 int $0x80 # вызвать системный вызов Однако в моей программе вывод всегда переходит в состояние «rejected_input», и я не знаю почему. Я новичок в сборке, поэтому не уверен, произошла ли ошибка программы, неправильное представление о том, как работает DFA, или и то, и другое.
