2015-04-19 6 views
4

On m'a dit de mettre des registres valides dans la pile pour ne pas les écraser plus tard dans le "sous-programme" et c'est clair pour moi, tout le monde le sait. Mais quand je lis le code de mes camarades, j'ai trouvé le code suivant:x86 Jeu d'assemblage de différences 'push'es et' pusha '

puts: ; display character in ax 
     push ax 
     push bx 
     push cx 
     push dx 
     mov dx, ax 
     mov ah, 9h 
     int 21h 
     pop dx 
     pop cx 
     pop bx 
     pop ax 
     ret 

Puis je vis pusha et popa commandes. Je suppose que cela pourrait se faire de cette façon:

puts: ; display character in ax 
     pusha 
     mov dx, ax 
     mov ah, 9h 
     int 21h 
     popa 
     ret 

Y at-il une différence entre le pusha et un ensemble de push es? Merci d'avance.

+5

Prenez garde que 'pusha' et' popa' sont des instructions 80286+. Si vous ciblez une machine 8086 ordinaire, cela ne fonctionnera pas. En fait, certains assembleurs peuvent avoir besoin de la directive '.286' pour les reconnaître comme des instructions valides. –

+0

N'utilise pas le .286 (directive point) considéré comme une mauvaise pratique? –

+1

Je ne peux pas imaginer pourquoi –

Répondre

3

Oui, pusha et popa sont équivalents, si seulement parce qu'ils poussent/pop tous les registres. Cependant, est-il nécessaire de le faire pour un simple appel d'interruption DOS?

Transfert à un programme d'interruption
...

Comme pour toutes les opérations, faites autant que nécessaire et nothi ng plus. Un appel d'interruption doit préserver les registres - à part ceux qui sont documentés pour changer. Les appels d'état normaux renvoient leur résultat au AX et peuvent changer les indicateurs, et ne rien changer d'autre. Si une interruption change quelque chose d'autre (ds:dx, par exemple), cela devrait être indiqué dans sa documentation.

Dans votre code, en utilisant ah=09/int 21, le seul changement est

Retour: AL = 24h

et ainsi tous les autres registres supposer sans risque "stockés".

Il existe une raison pour laquelle une interruption est conservée autant que possible. Globalement, une interruption (les «vrais», et non l'invocation par l'utilisateur) peut se produire à tout moment pendant que l'autre code est en cours d'exécution.

Il y a aussi une bonne raison pas pour utiliser pusha/popa sans discrimination. Votre pile a une taille limitée - bien sûr, elle est grande, mais le nombre de routines pouvant être imbriquées le sera également. Et dans les codes 32 et 64 bits, les registres sont également plus grands.

Chaque routine ne doit conserver que les registres qui sont connus pour changer, et en miroir, vous devez seulement enregistrer ceux dont vous aurez besoin plus tard avant que vous appelez une telle routine. Dans l'exemple de code, il n'y en a pas, donc vous pouvez supprimer en toute sécurité tout en poussant et en éclatant.

+0

Qui est le Tim McGuire que vous citez? L'article de 14 ans est-il fiable? – xmojmr

+6

Pour une architecture informatique vieille de 30 ans? Oui. – usr2564301

1

pusha enregistre encore quelques registres, notamment la valeur de sp avant d'exécuter, bp, si et di. A part ça, le comportement est à peu près identique.

3

L'opération pusha pousse plus que les ax, bx, cx et dx registres:

« pousse tous les registres d'usage général dans la pile dans l'ordre suivant: (E) AX, (E) CX (E) DX, (E) BX, (E) SP, (E) BP, (E) SI, (E) DI La valeur de SP est la valeur avant la pression réelle de SP. "

Vous pouvez faire essentiellement la même en appuyant sur les registres à l'aide de huit instructions push, mais qui poussera une valeur différente pour sp. Vous pouvez simplement omettre le pointeur de la pile car il n'y a pas besoin de le pousser. Pousser et poping les sept registres remplit le même but que pusha et popa même si elle doens't faire exactement la même chose:

push ax 
push bx 
push cx 
push dx 
push bp 
push si 
push di 
... 
pop di 
pop si 
pop bp 
pop dx 
pop cx 
pop bx 
pop ax 
+0

Je sais qu'il enregistre plus de registre, mais peut-il être remplacé dans l'exemple donné? –

+1

@onegrx Oui, aussi longtemps que vous remplacez les 'pop's par' popa'. :) –

+1

@onegrx: Vous ne pouvez pas répliquer le comportement exact de 'pusha' et' popa' avec seulement des instructions 'push' et' pop', mais vous pouvez remplir le même objectif. – Guffa