2010-05-11 6 views
2

Pour le code ci-dessous, si je veux convertir la boucle for en assembly en ligne, comment cela se fera-t-il? (Pardon le code bizarre, je viens de faire vers le haut.)Assemblage en ligne

1) Ceci est pour le x86, en utilisant Visual Studio

2) Ce "comment utiliser dans l'assemblage de la ligne" question, pas "comment optimiser ce code" question

3) Tout autre exemple sera bon. Je vais penser à un meilleur exemple de code dans ABIT.

OK J'espère que cela est un meilleur exemple:

int doSomething(double a, double b, double c) 
{ 
    double d; 
    for(int i=100;i<200;i++) 
    { 
     d = a*a + b*b + c*c; 
     if(d>i) 
      return (i-99); 
    } 
    return -1; 
} 
+6

Avez-vous une bonne raison de le faire? Un compilateur décent fera probablement un bien meilleur travail qu'un programmeur d'assembleur noob. Et quel CPU ciblez-vous? –

+3

Notez également que votre code a une expression redondante à l'intérieur de la boucle - la deuxième ligne est inutile car b est immédiatement remplacé par c. Vous pourriez vouloir corriger votre code avant d'essayer de l'optimiser. –

+3

Et une autre chose - la boucle elle-même est redondante car toutes les expressions à l'intérieur sont invariantes en boucle. Vous n'avez pas vraiment réfléchi à cela, n'est-ce pas? –

Répondre

5

Il serait probablement commencer quelque chose comme cet exemple incomplet et quelque peu inefficace. Devrait démontrer la syntaxe, cependant.

double doSomething(void) { 
    double a=1,b=2,c=3; 
    __asm { 
     mov ecx,10 
loop: 
     fld a // a 
     fmul st(0),st(0) // aa 
     fld b // b aa 
     fmul st(0),st(0) // bb aa 
     fsubp // aa-bb 
     fstp c // c = a*a-b*b 

     // and so on 

     dec ecx 
     jnz loop 
    } 
    return a+b+c; 
} 

L'utilisation d'instructions SSE serait une autre option.

assembleur en ligne ++ Le VC est documenté ici: http://msdn.microsoft.com/en-us/library/4ks26t93.aspx

Les manuels de référence du processeur Intel sont ici: http://www.intel.com/products/processor/manuals/

+0

Bonne réponse. +1 –

1

Vous pouvez optimiser ce sans avoir recours à l'assembleur:

double doSomething(void) 
{ 
    double a = 1.0, b = 2.0, c = 3.0; 
    c = a * a - b * b; 
    b = c; 
    return a + b + c; 
} 

Ou si vous augmentez le niveau d'optimisation:

double doSomething(void) 
{ 
    return -5.0; 
} 
+0

Pourquoi le vote à la baisse? Sans commentaire? C'est une réponse parfaitement valide à la question (telle qu'elle a été posée à l'origine). –

+1

Si quelqu'un voulait apprendre à calculer la valeur de pi à 5 décimales, il ne serait pas très utile de répondre "3.14159" à moins qu'il ne puisse revenir vers vous pour une nouvelle réponse quand il a décidé qu'il voulait 10 ou 100 décimales des endroits. Enseigner à un homme à pêcher ... – Dinah

+0

@Dinah: Eh bien, il y a un point sérieux ici, qui est souvent négligé, et c'est que vous devez optimiser à un niveau élevé avant de recourir à des micro-optimisations telles que l'assembleur codé à la main (qui devrait toujours être un dernier recours). En outre, la question posée initialement manquait de détails et de contexte, de sorte que l'on ne savait pas vraiment ce que le demandeur * essayait vraiment de faire. Les descendants heureux de nous-mêmes manquent souvent de tels points subtils. –

2

Totalement dépendant du compilateur et de l'architecture. Vous aurez besoin de parcourir le web pour des informations sur asm inline pour votre compilateur et ensuite apprendre les codes asm op pour votre architecture (dans le bon dialecte asm - dépendant du compilateur).

1

Aucun assemblage en ligne d'apprentissage réel. Ce n'est pas pris en charge pour x64 (avec Visual Studio, c'est-à-dire). Si vous utilisez x64 maintenant ou ne l'utilisez pas, à un moment donné, vous serez et en ligne sera l'histoire.

Mieux vaut apprendre à utiliser MASM à la place, où ce que vous apprendrez pour x86 sera toujours utile pour x64.

+2

J'ai vu beaucoup d'arguments "quel est le point" en ligne ces derniers temps. Je vous félicite de proposer une meilleure façon de faire les choses au cas où le PO ne les connaîtrait pas, mais en ce qui concerne «quel est le but» - qui se soucie de ce que le «point» est? Je n'ai même pas commencé à programmer avec un "point" en tête. Je l'ai fait parce que c'était amusant et intéressant. La plupart de mes programmes de passe-temps n'ont pas de "point" non plus, ils sont juste quelque chose que je veux faire. J'ai créé un langage de programmation ésotérique une fois que cela a fait très peu. Quel était le point? Car je voulais. – Dinah

+0

Alors que l'assembly inline n'est pas pris en charge pour 64 bits dans Visual Studio, l'assembly lui-même l'est. Fondamentalement, vous déclarez la fonction en C++, puis codez la fonction asm dans un fichier asm séparé et reliez-les lors de la construction de l'application. Bien que ce ne soit pas "inline" per se, c'est juste une autre façon de faire la même chose. Et cela compte - par exemple lors du codage de versions 32 bits et 64 bits d'un plugin VST (ou la conversion d'un plugin VST 32 bits en 64 bits). Voici un lien pour voir comment cela fonctionne: http://www.sciencezero.org/index.php?title=How_to_write_x64_assembly_functions_in_Visual_C%2B%2B –

0

Votre meilleure option est que le compilateur imprime le langage d'assemblage pour une fonction. Utilisez ceci comme référence pour l'assemblage en ligne.

En général, l'assemblage en ligne doit être évité car il est spécifique à la plate-forme, en particulier au processeur. Une meilleure solution consiste à placer la fonction dans un fichier distinct. Créez une version en langage C et une version en langage assembleur. Dans votre processus de construction, choisissez parmi les différents fichiers. Cela vous permettra d'avoir différentes versions en langage assembleur pour différentes plates-formes et processeurs avec des effets secondaires minimes pour le reste de votre programme (ce qui est très important).