первая инструкция push bp
, поэтому значение на вершине стека теперь значение из bp
.
Затем сделать еще некоторые вещи, в том числе манипуляции sp
(указатель на вершину стека), но как раз перед ret
она указывает обратно к старому bp
стоимости.
ret
выдает значение из стека и устанавливает ip
(указатель инструкции) на это значение. При нормальных обстоятельствах ожидается, что на вершине стека будет выведен адрес следующей инструкции (обычно там устанавливаются команды call
, который выполняет встречное действие ret
, адрес push следующей инструкции после call
на стек, а затем устанавливает ip
к значению аргумента от команды call
).
Но в вашем коде на ip
установлен в старом bp
значение, которое очень вероятно, точки где-то в памяти стека (или «хуже»), так что процессор будет следующей попытке выполнить байты данных в виде кода, а поведение является неожиданным (возврат к ОС будет на самом деле довольно приятным конечным результатом, такие ошибки обычно заканчиваются крахом приложения или даже потерей данных).
Чтобы исправить, добавьте pop bp
перед ret
(после восстановления sp
значение mov sp,bp
).
Всякий раз, когда вы манипулируете стек, либо явно push/pop
или add/sub sp
или неявно call/ret
, убедитесь, что вы в конечном с правильным sp
значения в каждом пути коды перед использованием стеки далее. То есть. обычно каждый push
нуждается в спаривании pop
, и каждый call
должен вернуться на ret
, если только вы не достаточно опытны, чтобы нарушать такие правила и корректировать стек для правильного состояния различными способами.
BTW, сомнительно, есть ли на самом деле является обратный адрес в стеке в вашей точке входа (это не ясно из вашего вопроса, если у вас есть какой-то другой код call
-ную это, или это точка входа вашей программы).
Если это похоже на исполняемый файл DOS, и это была точка входа, то вы должны завершить свою программу с помощью вызова службы ОС int 21h, 4Ch
.
Какой у вас ассемблер? Кроме того, вопрос не имеет смысла. Когда вы * запускаете * программу, * ассемблер * что-то делает? Ассемблер не выполняется, когда вы запускаете проблему.Вы видите это сообщение при попытке собрать свой код или при попытке запустить двоичный файл? Вы уверены, что это на самом деле ошибка? –
В чем вопрос? – fuz
Что такое код ** после ** 'call twoMash'? Вы не опубликовали его, но он, вероятно, заканчивает программу (например, «mov ax, 4c00h',' int 21h'). –