Registre sp

helloworld -  
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

Quelq'un peu t'il mexpliquer pourquoi cette opération est interdite?
Pourtant ont peu généralement utilisé un registre d'offset comme adresse?

mov ax, [sp]


Merci

2 réponses

Utilisateur anonyme
 
Bonjour

C'est en toutes lettres dans la doc Intel, l'adressage indirect par registre ne se fait que sur BX, BP, Si ou DI.
Et franchement, ça servirait à quoi un adressage indirect par [SP] ? Tu récupérerais la donnée qui est immédiatement au-dessus du sommet de la pile, ce qui n'a absolument aucun intérêt dans un programme réel.
0
helloworld
 
Cela parait logique ! mais j'ignorai qu'il y avait une doc, merci
0
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
Bonjour,

Ça doit plutôt être une limitation due au compilateur non?
Tu utilises quel logiciel?

@Le Père, l'adressage de la pile est inversé : L'offset est décrémenté lors de l'empilage, [SP] pointe donc sur le dernier élément empilé. L'utilisation de [SP +..] est très utile pour stocker ou lire les paramètres de fonction éventuellement placés sur la pile, ou même pour improviser un cadre de pile et y placer des variables temporaires...
Pour ma part je l'utilise même couramment en lieu et place d'empilage et dépilage car les push et pop sont bien plus lents.
0
Utilisateur anonyme
 
Ça doit plutôt être une limitation due au compilateur
Non, c'est une limitation du processeur. D'ailleurs, il ne s'agit pas de compilateur mais d'assembleur ici.
L'offset est décrémenté lors de l'empilage, [SP] pointe donc sur le dernier élément empilé
Non, car la décrémentation a lieu AVANT l'empilage. [SP] "tape" donc en dehors de la pile. Le sommet de la pile est en [SP+1].
Je suis très, très étonné et pour tout dire sceptique sur le fait que tu utilises couramment [SP+...] pour accéder au sommet de la pile. Tous les compilateurs que je connais recopient SP dans BP, puis utilisent [BP+..] pour les paramètres passés et [BP-..] pour les variables locales réservés au sommet de la pile. Et je viens de ressortir mon "ASM86 language Reference Manual" d'Intel (édition 1982), dans tous les modes d'adressage indirect par registre, avec ou sans déplacement, pas la moindre trace de [SP].
Peux-tu me donner le code hexa d'un MOV AX,[SP] (ou [SP+2] si tu préfères) pour que je puisse chercher à quoi ça correspond dans ma doc ?
0
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
Bonjour,

Oui je comprend ton scepticisme Le Père, surtout si ta doc dit que c'est impossible, cependant ma doc à moi (turbo assembleur memento 1992) dit que c'est tout à fait possible, SP pouvant être spécifié comme tout autre registre dans l'octet modR/M ou dans le Sib.
Par contre ma doc spécifie bien l'adressage possible via SP, mais mon compilateur la refuse en adressage 16 bits, il est donc possible que l'instruction n'existe qu'à partir du i386 et impose le 32 bits, ce qui expliquerait son absence de ta doc.
Le code relevé pour "Mov AX,[ESP] est : 8B0424

Et je parle de compilateur car le code assembleur est tout de même retravaillé, pour le moins transformé en codes hexa correspondants, et aussi car j'utilise l'assembleur sous Delphi, mais on chipote sur les mots,...

Les compilateurs copient effectivement SP dans BP puis décrémentent SP de manière à mettre en place un cadre de pile, c'est d'ailleurs le rôle des instructions asm Enter et Leave, mais ça n'empêche pas que les paramètres placés sur la pile doivent être lus ou écrits avec l'adressage [SP+..], sinon ils faudrait tous les dépiler pour accéder à celui voulu.
Et ce cadre de pile basé sur BP ne sert qu'à stabiliser la zone des variables temporaires, qui serait déplacée à la moindre modification de SP (Par un Push ou un Call par exemple).
Dans des routines rapides et assez courtes je préfère garder le registre EBP à d'autres fins. Je créé donc un cadre de pile basé sur ESP tout simplement en le décrémentant du nombre d'octet dont j'ai besoin, ce qui créé une zone libre de [ESP] à [ESP + Count-01]. Il n'y a plus qu'à incrémenter ESP pour libérer la zone et voilà. Et ça permet par exemple de sauvegarder des registres en entrée de fonction sans passer par des push et pop 3 ou 4 fois plus lents qu'un Mov [ESP],reg .

-> [SP] pointe bien sur la dernière variable empilée, car SP et décrémenté puis la valeur est fixée à partir de [SP].
C'est à dire que concrètement, si on empile un dword, SP est décrémenté de 4 puis la valeur écrite, donc le sommet de la pile reste en [SP].
Un prochain DWord empilé le serait à [SP-04] donc...
0
Utilisateur anonyme
 
Donc la possibilité d'utiliser [SP] n'existe pas en 8086, mais dans les versions ultérieures. Si Helloworld rencontre ce problème, c'est sans doute qu'il utilise un mode qui n'est compatible qu'avec le 8086.
S'il tient vraiment à utiliser cette instruction, il faut qu'il trouve l'option qui va bien dans son assembleur pour avoir accès à ce mode. Si c'était juste pour comprendre, je crois qu'il a la réponse maintenant.

Quand j'essaye de désassembler ton code hexa (à la main...) je tombe sur MOV AX,[SI] (avec 8B04 seulement, le 24 serait l'instruction suivante). Curieux, je m'attendais à trouver un code incompatible avec mon manuel.

Quant au fait que [SP] pointe bien dans la pile, et non pas au dessus, c'est évident, même si je me suis pris les pieds dans le tapis à ce sujet, et qu'en plus j'ai insisté ! Merci de m'avoir corrigé.
0
nicocorico Messages postés 799 Date d'inscription   Statut Membre Dernière intervention   138
 
Moi-même j'ai parlé trop vite, Le Père, je pensais que le préfixe 67h déterminait systématiquement l'adressage 16 bits ou 32 bits, alors que son implication est plus subtile...
Une prochaine fois c'est toi qui me corrigera pour sûr !

D'après ce que je lis, il est impossible d'utiliser le registre [SP] en adressage avec l'octet modR/M. En fait l'opcode 8B04 prend le sens "Mov AX,[SI] en adressage 16bits, tandis qu'en adressage 32 bits il prend un sens différent, il exige l'ajout de l'octet d'adressage Sib qui vient préciser [Base + Offset * multiplicateur] et dont la valeur 24 donne [ESP].

L'octet Sib est spécifique à l'adressage 32 bits et n'existe donc qu'à partir du 386, ça devrait fonctionner en réglant le compilateur sur la compatibilité 386 et en utilisant ESP.

D'ailleurs je ne comprend pas pourquoi continuer à utiliser l'asm 16 bits avec ses très nombreuses limitations? L'asm 32 bits est tellement plus souple et plus moderne, et il s'est imposé depuis le 386 tout de même, ça date..! En 32 bits on peut utiliser n'importe quel registre en adressage (grâce au Sib, ex: Mov ECX,[EAX + EDX*8]), multiplier toutes opérandes également via Imul, constante en prime (ex: Imul ECX,EDX,05), et évidemment taille de registres 32bits... le 16 bits est selon moi la version "casse-tête chinois" de l'asm, difficile à exploiter concrètement car les registres sont trop petits 50% du temps, les instructions sont rigides, il faut gérer les segments... La version 32 bits est elle parfaitement exploitable, et très simple à mettre en oeuvre grâce à des Edi type Delphi en version gratuite (c++ builder fait de même je crois), permettant d'insérer de l'asm en fonctions indépendantes ou en Inline dans le code, tout en autorisant l'exploitation des classes d'objets (appel de méthodes) et de toutes structures depuis l'asm, et reconnaissant les instructions MMx, SSe, 3D now!, 64 bits... le rêve!
Enfin je comprend que le 16 bits ait une finalité plus orientée matériel, mais si c'est pour pratiquer ou apprendre l'asm, il me semble que le 32 bits dans un Edi laisse plus de place au plaisir, avec conjointement le langage évolué pour sa simplicité et l'asm pour sa puissance...
0
Utilisateur anonyme
 
"Une prochaine fois c'est toi qui me corrigera "
corrigeras avec un "s"
Ça y est, c'est fait ;-)
Bonne soirée.
0