2017-06-07 4 views
-1

Comment faire le commutateur, la structure de cas en assembleur? Quelle est la bonne façon ou plus de corect?Faire interrupteur, structure de cas dans l'assemblage

Ceci est mon code en C, ce que je veux écrire en assembleur.

if (diode_on == 1) 
    { 
     switch(diode_num) 
      { 
      case 0: 
       //score += 3; 
       break; 

      case 1: 
       //score += 3;     
       break; 

      case 2: 
       //score += 3; 
       break; 

      case 3: 
       //score += 3; 
       break; 

      default: 
       break; 
      } 
     diode_on = 0; 
    } 

J'ai besoin de cela pour mon projet, MMSP430F5XX. La condition du projet est qu'une routine de rupture est écrite en assembleur. Et c'est un code de routine de rupture en C, ce que j'essaie d'écrire en assembleur.

#pragma vector=PORT2_VECTOR 
__interrupt void port2handler(void) 
{ 
    __delay_cycles(1000); 

    if (diode_on == 1) 
    { 
     switch(diode_num) 
      { 
      case 0: 
       if((P2IFG & BIT4)!=0) 
       { 
        if ((P2IN & BIT4)==0) 
         //score += 3; 
         calculationScore(3); 
       } 
       else 
        //score--; 
        calculationScore(-1); 
       break; 

      case 1: 
       if((P2IFG & BIT5)!=0) 
       { 
        if ((P2IN & BIT5)==0) 
         //score += 3; 
         calculationScore(3); 
       } 
       else 
        //score--; 
        calculationScore(-1); 
       break; 

      case 2: 
       if((P2IFG & BIT6)!=0) 
       { 
        if ((P2IN & BIT6)==0) 
         //score += 3; 
         calculationScore(3); 
       } 
       else 
        //score--; 
        calculationScore(-1); 
       break; 

      case 3: 
       if((P2IFG & BIT7)!=0) 
       { 
        if ((P2IN & BIT7)==0) 
         //score += 3; 
         calculationScore(3); 
       } 
       else 
        //score--; 
        calculationScore(-1); 
       break; 

      default: 
       break; 
      } 

     P4OUT &= ~(BIT3 | BIT4 | BIT5 | BIT6);   //gasimo diode 
     diode_on = 0; 
    } 

    P2IFG &= ~(BIT4 | BIT5 | BIT6 | BIT7);    // brisanje flega 
} 
+1

Le commutateur avec coupures est équivalent à –

+1

Pouvez-vous marquer une architecture, s'il vous plaît? Nous ne pouvons pas répondre sans. –

+0

nous pouvons répondre sans cela juste génériquement. il y a un certain nombre d'autres problèmes avec la question au-delà de ce qui fait qu'il est difficile de simplement donner à cette personne la réponse à leur question de devoirs. –

Répondre

1

Qu'avez-vous vu lorsque vous avez compilé ceci? Comment votre compilateur l'a-t-il résolu?

Sur le dessus de ma tête, il y a trois façons simples de l'implémenter mais pas toutes. Tout d'abord, un arbre if-then-else fonctionnera toujours, et en fonction de votre cas, les valeurs sont parfois la seule façon de le faire. Tout le reste est "ça dépend" alors disons par exemple que vous avez sorti vos commentaires et que vous vouliez ajouter 0,1,2,3 à la partition et toutes les autres valeurs non ... ET ... diode_num pourrait être l'un de ces numéros ou une autre valeur comme 75 ou même 4. alors vous pourriez/mettre en œuvre ce que:

if(diode_num&3) goto skip; 
score+=3; 
skip: 

bien sûr en C (sans goto si vous préférez) ou dans la syntaxe pour votre langage d'assemblage, quelle que soit la cible.

si le code que vous avez fourni est tel que diode_num ne peut être que 0,1,2,3 alors ce n'est pas un code mort, mais il optimise jusqu'à marquer + = 3 dans tous les cas et le commutateur s'en va. En supposant que ce ne soit pas le cas, un autre "ça dépend" est une table de saut qui dépend non seulement de vos valeurs de cas, mais aussi de l'ensemble des instructions et dépend de toutes les valeurs possibles, par exemple le code que vous avez fourni et en supposant que vous effectivement fait quelque chose pour chaque cas que le code que vous avez fourni est le plus souvent du code mort, il devient

if(diode_on == 1) diode_on = 0; 

vous devriez avoir fourni un meilleur exemple. mais si le compilateur et l'optimiseur peuvent voir le code que vous n'avez pas fourni et laisse dire trouve que la gamme possible de valeurs pour diode_num est 0-7 et que vous voulez faire quelque chose de spécial pour chacun de 0,1,2,3 et un tableau de sauts est possible dans ce jeu d'instructions que vous ne l'avez pas spécifié,

load some_register,table_base_add 
shift_left temp_register,diode_num,2 ;assuming 32 bit addresses 
add some_register,temp_register 
load another_register,[some_register] 
branch_to another_register 

table_base_add: .word table_base 
.align 
;jump table 
table_base: 
.word case0 
.word case1 
.word case2 
.word case3 
.word switch_end 
.word switch_end 
.word switch_end 
.word switch_end 

;case 0 code 
case0: 
do something 
b switch_end 
;case 1 code 
case1: 
do something 
b switch_end 
;case 2 code 
case2: 
do something 
b switch_end 
;case 3 code 
case3: 
do something 
b switch_end 
switch_end: 
code after switch 

si le compilateur ne peut pas déterminer la plage de valeurs d'entrée, il peut ou ne peut pas choisir d'essayer une table de saut.

vous pouvez le rendre encore plus optimisé, disons que la plage de diode_num était strictement de 0,1,2,3 et que vous vouliez faire quelque chose de différent pour chaque cas mais c'était très simple et dans ce cas j'utilise fixe instructions de taille pour cette optimisation supplémentaire.

load some_register,base_add 
shift_left temp_register,diode_num,4 
add some_register,temp_register 
branch_to some_register 

base_add: .word base 
base: 
    ;case 0 code 
    one instruction 
    b switch_end 
    nop 
    nop 
    ;case 1 code 
    one instruction 
    one instruction 
    one instruction 
    b switch_end 
    ;case 2 code 
    one instruction 
    one instruction 
    b switch_end 
    nop 
    ;case 3 code 
    one instruction 
    nop 
    nop 
    b switch_end 
    switch_end: 

dans ce cas, en supposant 16 octets (quatre 32 mots de bits) par cas, vous pouvez simplement ajouter ou ou les temps le cas 16 à l'adresse de base et sauter là-bas, pas de table de saut nécessaire que les mathématiques. Si les cas étaient 1,2,3,4 vous pourriez soustraire un puis multiplier par 16 (décalage gauche 4) puis ajouter à la base et y sauter.Puisque vous êtes le compilateur d'optimisation, vous pouvez toujours utiliser un arbre if then else pour l'implémenter, ou si vous en savez plus sur les spécificités de la plage d'entrées, le nombre de cas, la quantité de code par cas (qui est la première chose que vous devriez coder et construire le squelette autour d'elle) et le jeu d'instructions, alors vous pouvez peut-être optimiser.

+0

Demain je serai dans le laboratoire et testerai cette approche. Je vous écris, comment c'était .. :) – SakaSerbia