2016-11-07 1 views
1

J'apprends actuellement en langage assembleur et un projet sur lequel je travaille nous oblige à convertir un fichier c dans un fichier asm. J'essaye d'implémenter la boucle for du fichier c, et je me demande si je suis capable de stocker la variable de compteur à une adresse spécifique. Par exemple, si le compteur commence à 0, puis-je faire quelque chose comme ceci:Pouvez-vous utiliser une adresse spécifique pour stocker une variable en x86?

mov dword [ebp-0x4], 0 
for_loop: 
cmp dword [ebp-0x4], ecx 
jge break 
... 
... 
inc dword [ebp-0x4] 
jmp for_loop 
+0

Eh bien, oui, vous pouvez stocker une variable dans la mémoire. Vous voudrez probablement vous assurer que vous utilisez une adresse qui n'est pas déjà utilisée pour autre chose. Il y a aussi la question de 'réserver' vs 'commettre' de la mémoire (ou quel que soit l'équivalent d'unix). Mais peut-être la question la plus importante ici est pourquoi vous voulez le stocker en mémoire au lieu d'utiliser un registre. Habituellement, les compteurs sont de bons candidats pour cela. –

+1

En règle générale, l'assemblage du code vous dira si votre idée est totalement fausse ou non. Si le test "assembler" réussit, le passage du code à l'aide d'un débogueur règle (habituellement) la question. Pour cette question spécifique, les deux tests passent facilement. Pour la réponse définitive, vous pouvez consulter le manuel ISA –

+1

Gardez-le dans un registre. C'est plus facile et c'est plus rapide. Les variables de boucle en mémoire ralentissent votre code à moins que le corps de la boucle ne soit assez grand/trop lent pour que 5 cycles de latence supplémentaires ne le rendent pas un goulot d'étranglement. (Par exemple dans une boucle qui est déjà grand/lent et ne fonctionne pas plus vite que 6cycles par itération, en premier lieu.) –

Répondre

0

Votre code est correct. Mais l'accès à l'adresse mémoire spécifique dépend de cet emplacement d'adresse. Si cette adresse réside dans l'espace mémoire de votre programme, ce serait bien, d'une autre manière vous aurez une erreur de segmentation.

Pour plus d'informations sur x86, Intel 64 instructions et leurs opérandes vous pouvez vous référer à Intel® 64 and IA-32 Architectures Developer's Manual.

+0

a obtenu. Je vous remercie! – Mike

1

Vous pouvez utiliser le registre CX pour le stockage de compteur de boucle.

+0

Pourquoi 'cx'? Il peut utiliser n'importe quel registre qu'il veut (sauf 'eip', et utiliser' esp' comme registre général serait extrêmement difficile (impossible pour quelqu'un qui apprend juste l'assemblage) ... Utiliser 'cs' ou' ss' poserait aussi un certain défi pour le programmeur ... en fait 'cs' est faisable de façon ridicule, déroulant chaque étape de la boucle dans le segment de code différent ...: D). – Ped7g

+1

Eh bien, CX est connu pour être un compteur de boucle. C'est essentiellement ça.Vous avez certainement raison de pouvoir utiliser n'importe quel registre, mais utiliser CX, c'est comme utiliser des conventions de nommage, ça rend la vie meilleure :) – FCin

0

Cela fonctionnera si vous avez configuré ebp d'abord à quelque chose de raisonnable, où [ebp-4] est réservé pour votre compteur.

Donc, soit:

1) dans votre vous avez quelque chose comme le segment .data ou .bss:
counter: dd ? et vous faire lea ebp,[counter+4].

2) ou vous utilisez le ebp comme pointeur de cadre de pile (usage courant dans le code C compilé), comme push ebpmov ebp,esp au début de la fonction.

Ensuite, vous devez réserver l'espace pour les variables locales ([ebp - something]), généralement le mov ebp,esp est suivi par sub esp,<size of local vars>.

Sans ce esp ajustement le prochain push <something> remplacera [ebp-4] mémoire.

BTW, il est généralement bon de garder les valeurs utilisées dans la boucle intérieure dans les registres, pour des raisons de performance. Mais si vous êtes à court de registres, et que vous n'utilisez le compteur que pour la boucle, votre approche est valide.