Définition d’une variable dans un assemblage inline c ++

Disons que nous avons le code c ++ suivant:

int var1; __asm { mov var1, 2; } 

Maintenant, ce que j’aimerais savoir, c’est que, si je ne voulais pas définir var1 en dehors de la directive __asm, que devrais-je faire pour la mettre à l’intérieur? Est-ce même possible?

Merci

Pour ce faire, vous devez créer une méthode “naked” avec _declspec (naked) et écrire vous-même le prolog et l’épilogue normalement créés par le compilateur.

Le but d’un prolog est de:

  • mettre en place EBP et ESP
  • réserver de l’espace sur la stack pour les variables locales
  • des registres de sauvegarde qui doivent être modifiés dans le corps de la fonction

Un épilogue doit:

  • restaurer les valeurs de registre sauvegardées
  • nettoyer l’espace réservé aux variables locales

Voici un prolog standard

 push ebp ; Save ebp mov ebp, esp ; Set stack frame pointer sub esp, localbytes ; Allocate space for locals push  ; Save registers 

et un épilogue standard:

 pop  ; Restore registers mov esp, ebp ; Restore stack pointer pop ebp ; Restore ebp ret ; Return from function 

Vos variables locales commenceront alors à (ebp - 4) et descendront à (ebp - 4 - localbytes) . Les parameters de la fonction commencent à (ebp + 8) et vont vers le haut.

Les variables locales sont allouées et libérées en manipulant l’espace disponible sur la stack d’appels via le registre ESP, à savoir:

 __asm { add esp, 4 mov [esp], 2; ... sub esp, 4 } 

En règle générale, cela est mieux géré en établissant une “trame de stack” pour la fonction appelante, puis en accédant aux variables locales (et aux parameters de la fonction) en utilisant des décalages dans la trame, au lieu d’utiliser directement le registre ESP, à savoir:

 __asm { push ebp mov ebp, esp add esp, 4 ... mov [ebp-4], 2; ... mov esp, ebp pop ebp } 

Il est impossible de créer une variable C dans l’assembleur: le compilateur C doit connaître la variable (c’est-à-dire son type et son adresse), ce qui signifie qu’elle doit être déclarée dans le code C.

Ce qui peut être fait est d’accéder aux symboles définis dans l’assembleur via des déclarations extern en C. Cela ne fonctionnera pas pour les variables avec une durée de stockage automatique, car elles n’ont pas d’adresse fixe, mais sont référencées par rapport au pointeur de base.

Si vous ne souhaitez pas accéder aux variables en dehors du bloc asm , vous pouvez utiliser la stack pour stocker les données locales de l’assembleur. N’oubliez pas que vous devez restaurer le pointeur de stack à sa valeur précédente lorsque vous quittez le bloc asm , par exemple

 sub esp, 12 ; space for 3 asm-local 32bit vars mov [esp-8], 42 ; set value of local var [...] push 0xdeadbeaf ; use stack [...] ; !!! 42 resides now in [esp-12] !!! add esp, 16 ; restore esp 

Si vous ne voulez pas que les adresses relatives des variables locales changent chaque fois que vous manipulez la stack (utilisez push ou pop ), vous devez établir un cadre de stack (enregistrer la base de la stack dans ebp et les adresses locales relatives à cette valeur) comme décrit dans la réponse de cedrou .