web-dev-qa-db-fra.com

Fonction MUL en montage

J'essaie de faire une simple action de multiplication dans l'assemblage, mais pour une raison quelconque, je ne vois pas les registres changer lorsque la fonction MUL est marquée.

mov bx, 5    
mov cx, 10

mul cx
6
James Clark

Celles-ci sont appelées instructions , et elles spécifient les opérations à effectuer par le processeur. mov est un mnémonique pour mov e, tandis que mul est un mnémonique pour mul tiply. Les autres instructions courantes incluent add, sub et div. J'espère que vous pouvez comprendre quelle opération cela spécifie!

La plupart des instructions prennent deux paramètres. Dans le jargon technique, ceux-ci sont souvent appelés opérandes . La première (à gauche) est la destination , et la seconde (à droite) est la source . Donc, dans le cas de mov bx, 5, cela déplace la valeur littérale 5 dans le registre de destination bx. L'ordre de ces paramètres est évidemment important, car vous ne pouvez pas déplacer le contenu du registre bx dans la valeur littérale 5!

L'instruction mul est un peu étrange car certains de ses opérandes sont implicites. Autrement dit, ils ne sont pas explicitement spécifiés en tant que paramètres. Pour l'instruction mul, l'opérande de destination est codé en dur comme registre ax. L'opérande source est celui que vous passez en paramètre: il peut s'agir d'un registre ou d'un emplacement mémoire.

Par conséquent, vous pourriez imaginer que mul cx veux dire mul ax, cx, mais vous ne l'écrivez pas de cette façon car le registre de destination ax est implicite.

Maintenant, une instruction mul commande au processeur de multiplier l'opérande de destination par l'opérande source et de stocker le résultat dans la destination. En code, vous pouvez imaginer que mul cx se traduirait par ax = ax * cx. Et maintenant, vous devriez voir le problème: vous n'avez pas initialisé le contenu du registre ax, donc vous multipliez 10 (qui est la valeur que vous avez placée dans cx) par ce que les ordures ont été laissées dans ax. En tant que tel, le résultat n'a aucun sens!

Si vous voulez en fait faire 5 * 10, il vous suffit de changer un caractère dans votre code:

mov  ax, 5     ; ax = 5
mov  cx, 10    ; cx = 10
mul  cx        ; ax = ax * cx

Le résultat sera stocké dans ax, qui est le registre de destination implicite. Eh bien, techniquement, le résultat sera stocké dans dx:ax. Il s'agit d'une paire de registres , ce qui signifie que la partie haute du résultat sera stockée dans dx, tandis que la partie basse de la le résultat sera stocké dans ax. Pourquoi cette complication supplémentaire? Parce que la multiplication de deux valeurs de 16 bits peut entraîner une valeur supérieure à 16 bits! Le renvoi du résultat dans une paire de registres 16 bits permet à l'instruction mul de renvoyer un résultat 32 bits. Cependant, lorsque vous apprenez, vous n'avez pas à vous en préoccuper. Vous pouvez simplement ignorer la possibilité de débordement et extraire la partie basse du résultat de ax.

Et même si je suis sûr que ce n'est qu'un exemple de jouet, il n'y a vraiment aucune raison d'écrire du code qui multiplie deux constantes ensemble. Cela peut être fait au moment de la construction, soit en utilisant une calculatrice et en codant en dur la valeur, soit en écrivant symboliquement la multiplication des constantes et en laissant votre assembleur faire le calcul. C'est, mov ax, 50. Mais comme je l'ai dit, je suis sûr que vous le saviez déjà!

Si tout le reste échoue, consultez la documentation des instructions qui vous posent problème. Vous pouvez presque toujours trouver cela en ligne en recherchant sur Google le nom de l'instruction et "x86". Par exemple, la documentation mul peut être trouvée ici , ainsi que plusieurs autres sites. Ces informations peuvent être assez compliquées, mais avec un peu d'effort, vous devriez pouvoir extraire les informations dont vous avez besoin. Vous trouverez également de nombreuses autres informations et liens utiles dans le wiki de balises x86 .

mais pour une raison quelconque, je ne vois pas les registres changer lorsque la fonction MUL est marquée.

Je dois également souligner que, si vous utilisez un débogueur pour parcourir votre code, la ligne actuellement marquée/mise en surbrillance est la ligne qui est sur pour exécuter. Il n'a pas encore été exécuté, donc ses effets sur les registres, la mémoire, etc. ne seront pas encore visibles. Vous devez passer par-dessus l'instruction, de sorte que la marque/surbrillance se trouve sur la ligne suivante , puis vous verrez les effets de la précédente (juste -exécuté).

Si vous avez compris mon explication ci-dessus, après une instruction mul, vous devriez voir le contenu des registres ax et dx changer. Vous verrez également des indicateurs et le pointeur d'instruction changer, si votre débogueur affiche l'un d'eux. Rien d'autre ne devrait changer! (Le manuel de référence des instructions d'Intel ne répertorie aucun autre effet sur l'état architectural de la machine.)

30
Cody Gray