Quel est le but réel et l'utilisation des registres EDI et ESI dans l'assembleur?
Je sais qu'ils sont utilisés pour les opérations de chaîne pour une chose.
Quelqu'un peut-il également donner un exemple?
Quel est le but réel et l'utilisation des registres EDI et ESI dans l'assembleur?
Je sais qu'ils sont utilisés pour les opérations de chaîne pour une chose.
Quelqu'un peut-il également donner un exemple?
Réponses:
Il y a quelques opérations que vous pouvez seulement faire avec DI / SI (ou leurs homologues étendus, si vous ne l' avez pas appris ASM en 1985). Parmi ceux-ci sont
REP STOSB
REP MOVSB
REP SCASB
Qui sont, respectivement, des opérations de stockage, de chargement et de balayage répétés (= massifs). Ce que vous faites est de configurer SI et / ou DI pour pointer sur un ou les deux opérandes, peut-être mettre un compte dans CX et laisser ensuite déchirer. Ce sont des opérations qui fonctionnent sur un tas d'octets à la fois, et elles mettent en quelque sorte le processeur en mode automatique. Parce que vous ne codez pas explicitement les boucles, elles font leur travail plus efficacement (généralement) qu'une boucle codée à la main.
Juste au cas où vous vous poseriez la question: selon la façon dont vous configurez l'opération, le stockage répété peut être quelque chose de simple comme poinçonner la valeur 0 dans un grand bloc de mémoire contigu; MOVSB est utilisé, je pense, pour copier des données d'un tampon (enfin, n'importe quel tas d'octets) vers un autre; et SCASB est utilisé pour rechercher un octet qui correspond à un critère de recherche (je ne sais pas s'il s'agit uniquement d'une recherche d'égalité, ou quoi - vous pouvez le rechercher :))
C'est à cela que servent ces règlements.
SI
= Index source
DI
= Index de destination
Comme d'autres l'ont indiqué, ils ont des utilisations spéciales avec les instructions de chaîne. Pour la programmation en mode réel, le ES
registre de segment doit être utilisé avec DI
et DS
avec SI
comme dans
movsb es:di, ds:si
SI et DI peuvent également être utilisés comme registres d'index à usage général. Par exemple, le C
code source
srcp [srcidx++] = argv [j];
se compile en
8B550C mov edx,[ebp+0C]
8B0C9A mov ecx,[edx+4*ebx]
894CBDAC mov [ebp+4*edi-54],ecx
47 inc edi
où ebp+12
contient argv
, ebx
est j
et edi
a srcidx
. Notez que la troisième instruction utilise edi
multiplié par 4 et ajoute un ebp
décalage de 0x54 (l'emplacement de srcp
); les parenthèses autour de l'adresse indiquent l'indirection.
AX
= accumulateur
DX
= double mot accumulateur
CX
= compteur
BX
= registre de base
Ils ressemblent à des registres à usage général, mais il existe un certain nombre d'instructions qui (de façon inattendue?) Utilisent l'une d'entre elles - mais laquelle? - de manière implicite.
Des opcodes comme MOVSB et MOVSW qui copient efficacement les données de la mémoire pointée par ESI vers la mémoire pointée par EDI. Donc,
mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
En plus des opérations de chaîne (MOVS / INS / STOS / CMPS / SCASB / W / D / Q etc.) mentionnées dans les autres réponses, je voulais ajouter qu'il existe également des instructions d'assemblage x86 plus «modernes» qui utilisent implicitement à moins EDI / RDI:
L' instruction SSE2 MASKMOVDQU
(et la prochaine AVX VMASKMOVDQU
) écrit sélectivement les octets d'un registre XMM vers la mémoire pointée par EDI / RDI.
En plus des registres utilisés pour les opérations de masse, ils sont utiles pour leur propriété d'être préservés par un appel de fonction (appel préservé) dans la convention d'appel 32 bits. Les ESI, EDI, EBX, EBP, ESP sont préservés des appels tandis que EAX, ECX et EDX ne sont pas préservés des appels. Les registres préservés des appels sont respectés par la fonction de bibliothèque C et leurs valeurs persistent lors des appels de fonction de bibliothèque C.
Jeff Duntemann dans son livre de langage d'assemblage a un exemple de code d'assemblage pour imprimer les arguments de ligne de commande. Le code utilise esi et edi pour stocker les compteurs car ils ne seront pas modifiés par la fonction de bibliothèque C printf. Pour les autres registres comme eax, ecx, edx, il n'y a aucune garantie qu'ils ne soient pas utilisés par les fonctions de la bibliothèque C.
https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025
See section 12.8 Comment C voit les arguments de ligne de commande.
Notez que les conventions d'appel 64 bits sont différentes des conventions d'appel 32 bits, et je ne sais pas si ces registres sont préservés ou non.