Обычно для конечного автомата вы пишете его как одну функцию, используя jmp
вместо call
для перехода в следующее состояние.
Ваше состояниефункции никогда не возвращаются, они всегда переходят в новое состояние (или для повторного запуска текущего состояния, например call s1
в нижней части s1
.). ret
в конце никогда не достигается, поэтому выпросто нажимая постоянно растущее количество адресов возврата, которые мешают вам на самом деле вернуться к main
.
Используйте метки типа s1:
вместо s1 proc
.Или вы все еще можете использовать этот синтаксис MASM, чтобы представить, что каждая из них является отдельной функцией, но использовать jmp s2
для вызова следующего состояния.
Затем, когда вы обнаружите условие завершения в качестве следующего состояния, вы можете ret
, и он вернется к main
.
Это имеет большое преимущество в том, что вы можете использовать условные ветви, такие как jne s1
вместо того, чтобы перепрыгивать через вызов / jmp .Синтаксис MASM .if
может быть недостаточно мощным, чтобы сделать это за вас, но вы все равно получаете огромные пропущенные оптимизации при использовании этого.Например, a==0 && b==0
можно проверить с помощью mov eax, a
/ or eax, b
/ jz both_were_zero
.Кроме того, имея только 2 «переменные», сохраняйте их в сохраняемых вызовах регистрах, таких как ebx
и esi
или что-то в этом роде, вместо того, чтобы вообще хранить их в памяти.Вот для чего нужны регистры!Вы пишете в asm
Кроме того, вы можете оптимизировать, выложив их так, чтобы s3
мог провалиться в s1
вместо окончания jmp s1
.Или будь проще и держи jmp
.(Если бы я выполнял эту оптимизацию, я бы оставил jmp s1
в качестве комментария в качестве документации о том, что переход к s1
в качестве следующего состояния является преднамеренным.)
Остальная часть вашего кода вложена в ваш main proc
, что странно , но, возможно, не вызывает реальной проблемы.Но первый блок кода с началом main
показывает, что он падает с call waitmsg
на myexit proc
?Это очень странно, но на самом деле должно работать, если myexit
- то, чего вы хотите.
Кроме того, у вас нет строки main endp
до конца файла, поэтому вы сообщаетеассемблер, что другие proc
декларации находятся внутри main
.