2017-01-04 2 views
-3

Quand je lance mon programme l'assembleur dit:est de retour contrôle au système d'exploitation à l'Assemblée 8086

PROGRAMME A REMIS DE CONTRÔLE DU SYSTÈME D'EXPLOITATION

lorsqu'il atteint la RET instruction. Le code ressemble à:

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

    NOT ax 
    ADD ax,1 

    mov sp,bp 
    ret 
twoMash ENDP 

main est défini ainsi:

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

Quel assembleur utilisez-vous? En outre, la question n'a pas de sens. Lorsque vous * exécutez * le programme, le * assembleur * fait quelque chose? L'assembleur ne s'exécute pas lorsque vous exécutez le problème.Voyez-vous ce message lorsque vous tentez d'assembler votre code ou lorsque vous tentez d'exécuter le code binaire? Êtes-vous sûr que c'est en fait une erreur? –

+1

Quelle est votre question? – fuz

+0

Quel est le code ** après ** 'appel twoMash'? Vous ne l'avez pas posté mais cela termine probablement le programme (comme 'mov ax, 4c00h',' int 21h'). –

Répondre

2

La première instruction est push bp, si la valeur au-dessus de la pile est maintenant la valeur de bp.

Ensuite, vous faire plus de choses, y compris la manipulation de sp (pointeur vers le haut de la pile), mais juste avant ret il pointe vers l'ancienne valeur bp.

ret va afficher la valeur de la pile, et définir ip (pointeur d'instruction) à cette valeur. Dans des circonstances normales, on s'attend à avoir sur la pile l'adresse de la prochaine instruction à exécuter (mettre généralement par call instructions, ce qui fait la contre-action de ret, pousser l'adresse de l'instruction suivante après call sur la pile, puis les ensembles ip à la valeur d'argument de call instruction).

Mais dans votre code le ip est défini à l'ancienne, de sorte que la CPU valeur bp, qui points très probablement quelque part dans la mémoire de la pile (ou « pire ») tentera ensuite d'exécuter octets de données sous forme de code, et le comportement est inattendu (retour à OS serait en fait assez agréable résultat final, de telles erreurs se terminent généralement par un crash d'application, voire une perte de données).

Pour corriger, ajouter pop bp avant ret (après avoir restauré la valeur sp par mov sp,bp).

Chaque fois que vous manipuler la pile, soit explicitement par push/pop ou add/sub sp, ou implicitement par call/ret, assurez-vous que vous finissez avec la valeur correcte sp dans chaque chemin de code avant d'utiliser la pile plus loin. C'est à dire. Habituellement, chaque push a besoin de son appariement pop et chaque call devrait revenir par ret, sauf si vous êtes suffisamment expérimenté pour enfreindre de telles règles et ajuster la pile à l'état correct par différents moyens.


BTW, on peut se demander, s'il y a effectivement est adresse de retour à la pile à votre point d'entrée (il ne sait pas de votre question, si vous avez un autre code call -ment cela, ou il est point d'entrée de votre programme).

Si cela ressemble à un exécutable DOS, et qu'il s'agissait d'un point d'entrée, alors vous devriez terminer votre programme avec un appel de service int 21h, 4Ch.