web-dev-qa-db-fra.com

Quel est le 0x10 dans l'instruction d'assemblage "leal 0x10 (% ebx),% eax" x86?

Quelle est la fonction du 0x10 par rapport à cette instruction LEAL? Est-ce une multiplication ou un ajout ou est-ce autre chose?

leal 0x10(%ebx), %eax

Quelqu'un peut-il s'il vous plaît clarifier? C'est un assembleur x86 sur une machine Linux.

32
Tony The Lion

leal ou lea nom complet est "Load effective address" et il fait exactement ceci: Il calcule une adresse.

Dans votre exemple, le calcul de l'adresse est très simple, car il ajoute simplement un décalage à ebx et stocke le résultat dans eax:

eax = ebx + 0x10

lea peut faire beaucoup plus. Il peut ajouter des registres, multiplier des registres avec les constantes 2, 4 et 8 pour le calcul d'adresse de mots, d'entiers et de doublons. Il peut également ajouter un décalage. 

Notez que lea a la particularité de ne jamais modifier les drapeaux, même si vous l'utilisez comme un simple ajout, comme dans l'exemple ci-dessus. Les compilateurs exploitent parfois cette fonctionnalité et remplacent un ajout par un lea pour aider le planificateur. Pour cette raison, il n’est pas rare de voir des instructions de calcul faire de l’arithmétique simple en code compilé.

71
Nils Pipenbrinck

lea signifie "adresse efficace de chargement"; c'est une façon d'utiliser les modes d'adressage sophistiqués du jeu d'instructions IA32 pour faire de l'arithmétique. Le suffixe l est un moyen de distinguer la taille des opérandes dans la syntaxe de GNU en tant que celle que vous avez sur votre machine Linux.

Donc, en bref, oui, c'est une sorte d'instruction d'addition. Il peut également gérer des multiplications par 2, 4 ou 8 en même temps.

Voir aussi cette question connexe (où ils utilisent la syntaxe Intel pour discuter de la même instruction): 

4
Pascal Cuoq

GNU en tant que 2.18 docs

https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html

AT & T: -4 (% ebp), Intel: [ebp - 4]

et puis la syntaxe Intel est explicite.

Plus important encore, les docs expliquent également le cas général:

Une référence de mémoire indirecte de syntaxe Intel du formulaire

 section:[base + index*scale + disp]

est traduit dans la syntaxe AT & T

 section:disp(base, index, scale)

où base et index sont les registres de base et d'index 32 bits facultatifs, disp est le déplacement facultatif, et scale, prenant les valeurs 1, 2, 4 et 8, multiplie l'index pour calculer l'adresse de l'opérande.

Les choses se compliquent quelque peu chez AT & T lorsque nous omettons certaines parties de l'adresse, par exemple. -4(%ebp), mais avec les exemples de la documentation, nous pouvons facilement en déduire tous les cas de syntaxe.

Pour bien comprendre ce qui se passe, je vous recommande de regarder comment les instructions sont codées. Ceci est un bon tutoriel: http://www.c-jump.com/CIS77/CPU/x86/lecture.html Quand vous verrez cela, vous comprendrez pourquoi certaines parties de l'adresse peuvent être omises et ce que chaque forme va compiler.

Pour ajouter à la réponse de Nils,

Pour rappel, le mode d'adressage dans IA32 assembleur est généralement de la forme:

IO (Rb, Ri, s), où: 

IO = décalage immédiat

Rb = Registre de base

Ri = registre d'index

s = facteur d'échelle {1, 2, 4, 8}

L'adresse effective est donc calculée comme suit: * IO + [Eb] + [Ei] s

leal ressemble à d’autres instructions comme movl, mais c’est un peu spécial. Au lieu de lire de la source à la destination, il copie l'adresse effective De la source à la destination. 

Ainsi, il peut être utilisé pour générer des pointeurs pour des références de mémoire ultérieures, ainsi que Pour des opérations arithmétiques de base, comme l'a souligné Nils. 

Par exemple:

laissez le registre% edx contenir une valeur de x

leal 1 (% edx,% edx, 8),% eax 

chargera l'adresse effective de 1 + x + 8 * x = 1 + 9x pour enregistrer% eax. 

En substance, l'opération:

leal source, destination => destination = adresse de source

Si vous connaissez C, c'est l'équivalent de:

char * b = & a;

où l'adresse de char a est attribuée au pointeur b

plus d'exemples:

Laisser enregistrer% eax maintenir la valeur x et enregistrer% ecx maintenir la valeur y

leal (% eax,% ecx, 4),% edx assignera la valeur x + 4y pour enregistrer% edx

leal 0xB (,% ecx, 5),% edx attribuera la valeur 0xB + 5y = 11 + 5y à% edx

leal (% eax,% eax, 2),% eax attribuera la valeur 3x pour enregistrer% eax

J'espère que cela t'aides

0
Kelvin Spencer