문제
나는 Windows Vista 아래에서 실행되는 MASM32에서 루프를 만들려고 노력하고 있지만, 이런 식으로 그렇게했는데 실제로 루프가 끝나더라도 충돌하고 그 이유는 없습니다.
.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
어셈블리 프로그래밍을 할 때 이런 식으로 이렇게했습니다. 카운터를 줄이고 0이 아닌 경우 루프.
loop_start:
invoke StdOut, addr ProgramText
dec loop_stopper
jnz loop_start
ret
물론 프로세서에 따라 루프 변수를 레지스터에 넣어 단일 명령어를 사용하여 줄이고 루프 할 수 있습니다. (예 : Z80 'DJNZ'명령. 'B'레지스터가 종을 울리는 것처럼 보이지만 실제로 등록한 것을 기억할 수 없습니다).
또한 다른 사람들이 제안한 것처럼 메모리 공간을 청소하는 것처럼 보이지 않습니다. 대부분의 프로그램은 실제로 코드에 대한 '전화'입니다. 따라서 운영 체제의 호출 부분에 우아한 "반환"을 수행 할 수 있도록 코드와 포인터를 보존해야합니다. 당신이 그렇게하지 않았다면, 당신의 '반품'은 스택의 상단이 가리키는 곳으로, 일반적으로 비참한 결과를 초래할 수 있습니다.
Clubpetey가 옳습니다. Masm은 코드에 대한 에피 로지를 생성하지 않습니다. 따라서 프로세서는 마지막 서면 지침 뒤에서 찾은 내용을 계속 실행합니다. 종료는 운영 체제에 프로그램 실행을 중단하도록 명시 적으로 요청합니다.