Je me souviens avoir vu un moyen d'utiliser l'assemblage étendu gcc en ligne pour lire une valeur de registre et la stocker dans une variable C. Je ne peux pas cependant pour la vie de moi se rappeler comment former la déclaration d'asm. Toute aide est très appréciée.Lecture d'une valeur de registre dans une variable C
Répondre
Vous vous rendez compte que cela va lire une variable, calculer le sinus et ensuite stocker le résultat dans une deuxième variable. –
@Samuel: C'était un exemple de syntaxe seulement. –
Downvoted, car il s'agit d'un exemple d'utilisation de l'assembly étendu dans GCC, pas de la façon d'obtenir la valeur d'un registre spécifique dans une variable spécifique, comme l'OP l'a demandé. En spécifiant les registres en utilisant '% 0' et'% 1', GCC choisira le registre en question en votre nom. Il n'y a aucune garantie qu'il choisira le registre que vous espérez. –
Je ne sais pas gcc, mais voici comment VS:
int data = 0;
__asm
{
mov ebx, 30
mov data, ebx
}
cout<<data;
Essentiellement, je me suis déplacé les données ebx
à votre variable data
.
x86 seulement, bien sûr. Les compilateurs Microsoft pour x64 et Itanium ne prennent pas en charge l'assemblage en ligne. – ephemient
Je pense que l'assemblée sera traduite en mov ebx, 30 mov dword ptr [données], ebx – Sridarshan
Pourquoi ne pas simplement 'mov données, 30'? – Houssni
est ici un moyen d'obtenir EBX:
int main()
{
int i;
asm("\t movl %%ebx,%0" : "=r"(i));
return i + 1;
}
Le résultat:
main:
subl $4, %esp
#APP
movl %ebx,%eax
#NO_APP
incl %eax
addl $4, %esp
ret
Edit:
Le "= r" (i) est une contrainte de sortie, dire au compilateur que la première sortie (% 0) est un registre qui devrait être placé dans la variable "i". À ce niveau d'optimisation (-05), la variable i n'est jamais stockée en mémoire, mais est conservée dans le registre eax, qui est également le registre de valeurs de retour.
J'utiliserais la contrainte '= rm' plutôt que' = r'. L'optimiseur du compilateur tentera de choisir le meilleur chemin. Si l'assembleur en ligne se trouve dans un registre, la situation affamée '= r' peut le forcer à générer un code moins qu'optimal. '= rm' donnerait à l'optimiseur une chance d'utiliser une référence mémoire si c'était le meilleur choix. Dans cet exemple simple, ce ne sera pas un problème, mais si le code est dans une situation plus complexe, alors donner des options au compilateur pourrait être bénéfique. –
Cela va déplacer le registre du pointeur de pile dans la variable sp.
intptr_t sp;
asm ("movl %%esp, %0" : "=r" (sp));
il suffit de remplacer « esp » avec le réel que vous enregistrez intéresse (mais assurez-vous de ne pas perdre le %%) et « sp » avec votre variable.
Aller dans une direction différente que les autres réponses jusqu'à présent, puisque je ne suis pas sûr de ce que vous voulez.
GCC Manual § 5.40 Variables in Specified Registers
register int *foo asm ("a5");
Ici
a5
est le nom du registre qui doit être utilisé & hellip;Naturellement, le nom du registre dépend de la CPU, mais ce n'est pas un problème, car des registres spécifiques sont le plus souvent utiles avec des instructions d'assembleur explicites (voir Extended Asm). Ces deux choses exigent généralement que vous conditionniez votre programme selon le type de CPU.
La définition d'une telle variable de registre ne réserve pas le registre; il reste disponible pour d'autres utilisations dans des endroits où le contrôle de flux détermine que la valeur de la variable n'est pas active.
GCC Manual § 3.18 Options for Code Generation Conventions
-ffixed-
regTraiter le registre nommé reg comme registre fixe; le code généré ne devrait jamais s'y référer (sauf peut-être en tant que pointeur de pile, pointeur de cadre ou dans un autre rôle fixe).
Cela peut répliquer la réponse de Richard d'une manière plus simple,
int main() {
register int i asm("ebx");
return i + 1;
}
bien que ce soit plutôt vide de sens, que vous ne savez pas ce qui est dans le registre ebx
.
Si vous combiné ces deux, la compilation de cela avec gcc -ffixed-ebx
,
#include <stdio.h>
register int counter asm("ebx");
void check(int n) {
if (!(n % 2 && n % 3 && n % 5)) counter++;
}
int main() {
int i;
counter = 0;
for (i = 1; i <= 100; i++) check(i);
printf("%d Hamming numbers between 1 and 100\n", counter);
return 0;
}
vous pouvez vous assurer qu'une variable C utilise toujours réside dans un registre pour un accès rapide et ne sera également pas faussés par d'autres code généré. (Jouissant d'une, ebx
est-sauvegarder sous callee x86 habituelles conventions d'appel, même si elle se mal par les appels vers d'autres fonctions compilées sans -ffixed-*
, il faut pas trop restauré.)
D'autre part, cela est certainement pas portable, et n'est généralement pas un avantage de performance non plus, car vous restreignez la liberté du compilateur.
A partir de la documentation du CCG se http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html:
Et comment savez-vous ce qui est dans EBX lorsque votre code C commence à exécuter? – florin