2017-01-04 3 views
-3

Когда я запускаю мою программу ассемблер говорит:программы вернула управление операционной системы в сборе 8086

ПРОГРАММА ВЕРНУЛАСЬ CONTROL для операционной системы

, когда он достигает RET инструкция. Код выглядит следующим образом:

twoMash PROC 
    push bp 
    mov bp, sp 
    sub sp, 2 

    NOT ax 
    ADD ax,1 

    mov sp,bp 
    ret 
twoMash ENDP 

main определяется следующим образом:

main: 
    mov ax,100b 
    push ax 
    call twoMash 
+0

Какой у вас ассемблер? Кроме того, вопрос не имеет смысла. Когда вы * запускаете * программу, * ассемблер * что-то делает? Ассемблер не выполняется, когда вы запускаете проблему.Вы видите это сообщение при попытке собрать свой код или при попытке запустить двоичный файл? Вы уверены, что это на самом деле ошибка? –

+1

В чем вопрос? – fuz

+0

Что такое код ** после ** 'call twoMash'? Вы не опубликовали его, но он, вероятно, заканчивает программу (например, «mov ax, 4c00h',' int 21h'). –

ответ

2

первая инструкция 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.

Смежные вопросы