Вопрос
Я пытаюсь создать цикл в masm32, работающем под Windows Vista, однако я сделал это таким образом, и хотя цикл фактически завершается, он выходит из строя, и я не вижу очевидной причины, почему... есть идеи?
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
ProgramText db "Looping!", 0
.data?
loop_stopper dd ?
.code
start:
mov loop_stopper,2
loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper
jg loop_start
end start
Редактировать
Делал
invoke StdOut, offset ProgramText
все равно вылетает...
Решение
Вам нужен «выход», чтобы завершить приложение.Кроме того, мой личный стиль — помещать все в подпрограмму, но это только я.
что-то вроде:
.code
начинать:
call main
inkey
exit
основной процесс
mov loop_stopper,2
loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper
jg loop_start
ret
основной конечный пункт
end start
Другие советы
Мне кажется, порядок ваших инструкций неправильный.Делаешь сравнение, потом уменьшение, потом условный переход.Значения ваших флагов из сравнения могут быть изменены декрементом.
loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper
jg loop_start
ret
Когда я занимался программированием на ассемблере, я делал это следующим образом:уменьшите счетчик, затем выполните цикл, если он не равен нулю.
loop_start:
invoke StdOut, addr ProgramText
dec loop_stopper
jnz loop_start
ret
Конечно, в зависимости от процессора вы можете поместить переменную цикла в регистр, который позволит вам уменьшать и выполнять цикл с использованием одной инструкции.(например, инструкция Z80 «djnz».Я не могу вспомнить, какой именно регистр это был на самом деле, хотя регистр «B», кажется, звонит в колокольчик).
Кроме того, как предположили некоторые другие, вы, похоже, не очищаете пространство своей памяти.Большинство программ на самом деле являются «вызовами» вашего кода.Поэтому вам необходимо сохранить указатели кода и стека, чтобы можно было выполнить корректный «ВОЗВРАТ» к вызывающей части операционной системы.Если вы этого не сделали, ваш «ВОЗВРАТ» может привести вас туда, куда указывает вершина стека, обычно с катастрофическими последствиями.
КлубПити прав.MASM не создает эпилог для вашего кода.Таким образом, процессор продолжает выполнение того, что он обнаружил за последней записанной инструкцией.exit явно просит операционную систему прекратить выполнение программы.