2009-02-10 14 views
1

J'essaye de faire une boucle dans masm32 fonctionnant sous Windows Vista, mais je l'ai fait de cette façon et même si elle finit réellement la boucle, elle plante et je ne vois pas pourquoi ... des idées?MASM32 loop

.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 

Modifier

Avez-

invoke StdOut, offset ProgramText 

encore ... crashes

+0

Même si c'était il y a 7 ans, il était le premier sur ma recherche google alors je suggère de mettre un 'INVOKE ExitProcess, 0' Au fond. – user2913685

Répondre

5

Vous devez avoir une "sortie" pour terminer votre application. Aussi, mon style personnel est de tout mettre dans un sous-programme, mais c'est juste moi.

quelque chose comme:
.code

start:

call main 
inkey   
exit 

main proc

mov loop_stopper,2 
loop_start: 

invoke StdOut, addr ProgramText 
cmp loop_stopper, 0 
dec loop_stopper 
jg loop_start 
ret 

main endp

end start

1

ClubPetey est exact. MASM ne produit pas d'épilogue pour votre code. Ainsi, le processeur continue l'exécution de ce qu'il trouve derrière la dernière instruction écrite. exit demande explicitement au système d'exploitation d'arrêter l'exécution du programme.

2

Il me semble que l'ordre de vos instructions est erroné. Vous faites une comparaison, puis un décrément, puis un saut conditionnel. Vos valeurs de drapeau de la comparaison pourraient éventuellement être modifiées par le décrément. Lorsque je faisais de la programmation d'assemblage, je l'ai fait de la façon suivante: décrémenter le compteur, puis boucler si non-zéro.

loop_start: 

    invoke StdOut, addr ProgramText 

    dec loop_stopper 
    jnz loop_start 

    ret 

Bien sûr, en fonction du processeur, vous pourriez mettre la boucle variable dans un registre qui vous permet de décrémenter et boucle à l'aide d'une seule instruction. (par exemple l'instruction 'djnz' du Z80, je ne me souviens plus de ce qui s'est passé en réalité, bien que le registre 'B' semble sonner une cloche).

En outre, comme d'autres l'ont suggéré, vous ne semblez pas nettoyer votre espace mémoire. La plupart des programmes sont réellement des 'APPELS' à votre code. Par conséquent, vous devez conserver le code et les pointeurs de pile de sorte que vous effectuiez un "RETURN" gracieux à la partie appelante du système d'exploitation. Si vous ne l'avez pas fait, votre «RETOUR» peut vous mener à l'endroit où le sommet de la pile pointe, généralement avec des conséquences désastreuses.

+0

Que ferions-nous si l'on faisait une boucle * vers le haut * à partir de zéro et que l'on voulait s'arrêter lorsque le compteur atteignait une valeur prédéterminée supérieure à zéro? – ApproachingDarknessFish