2017-09-30 6 views
-1

J'essaie de convertir un programme C en un programme d'assemblage MIPS. Ce qui suit est mon code C pour le programme: (Note: Ampoules [numéro] est un tableau initialisé à toutes les valeurs zéro pour un « nombre » entré par l'utilisateur)Conversion d'un programme C en programme de langage assembleur MIPS

for(int i = 1; i <= number; i++) 
      for(int j = 1; j <= number; j++) 
       if(j % i == 0) 
        Bulbs[j-1] = (Bulbs[j-1] + 1) % 2; 

Ce que j'ai à ce jour est la suivante :

li $t0, 0     #$t0 is set to 0 to be used as index for for loop1 
li $t1, 0     #$t1 is set to 0 to be used as index for for loop2 

li $s2, 4     #integer 4 is stored in s2 
mult $s3, $s2    #input number($s3) is multiplied by 4 
mflo $s4     #result of multiplication is stored in $s4 

loop1: 
bgt $t0, $s4, end_loop1  #if t$0 > $s4(input number*4), exit loop1, 
          #performing multiplication by 4 since word occupies 4 bytes 
addi $t3, $t3, 1    #t3 is initialized to serve as "i" from for loop1 
loop2: 
    bgt $t1, $s4, end_loop2 #if $t1 > (input number*4), exit loop2 
    addi $t4, $t4, 1   #t4 is initialized to serve as "j" from for loop2 
    div $t4, $t3 
    mfhi $t5    #$t4 % $t3 is stored in $t5 
    bne $t5, $zero, if_end #checking for if condition 

    if_end: 
    addi $t1, $t1, 4  #increment $t1 by 4 to move to next array element 
    j loop2     #jump back to top of loop2 

end_loop2: 
addi $t0, $t0, 4   #increment $t0 by 4 
j loop1      #jump back to the top of loop1 

end_loop1: 

Je pense que mes travaux de mise en œuvre en boucle et je le si elle est conditionnelle mise en place avec précision (corrigez-moi si je me trompe), mais je ne sais pas comment je peux mettre en œuvre les « ampoules [j- 1] = (Bulbes [j-1] + 1)% 2; ligne après mon si conditionnel. Je suis nouveau à MIPS et j'apprécierais n'importe quelle aide ou rétroaction!

+4

"Convertir" du code C en code d'assemblage, n'est-ce pas le travail d'un * compilateur *? ;) –

+4

Ce convertisseur est appelé "le compilateur" et il est beaucoup mieux que 99,99% de convertisseurs humains - voici votre code; https://godbolt.org/g/CPZtob –

+0

Hé @ PeterJ_01, beaucoup de ceci a du sens. Mais qu'est-ce que les lignes comme $ LFB24 =. et $ LBB5 =. représenter? –

Répondre

0

Je suppose que vous avez défini Bulbs comme un tableau quelque part. Puis

Bulbs[j-1] = (Bulbs[j-1] + 1) % 2; 

devrait être traduit à quelque chose comme:

la $t7, Bulbs # Move base pointer of bulbs to $t7 
add $t7, $t7, $t1 # $t7 = &Bulbs[j] 
lw $t6, -4($t7) # $t6 = Bulbs[j - 1] 
addi $t6, $t6, 1 # $t6 = Bulbs[j - 1] + 1 
andi $t6, $t6, 1 # $t6 = (Bulbs[j - 1] + 1) % 2 
sw $t6, -4($t7) # Bulbs[j - 1] = $t6 

Ceci est basé sur this information. Je n'ai pas encore fait d'assemblage MIPS, mais c'est RISC, alors à quel point peut-il être difficile? :)

Par ailleurs, il semble y avoir un bug dans votre traduction d'assemblage. Dans la version C, votre j commence à 1, alors que dans la version d'assemblage, il semble commencer à 0 (l'index $t1 est initialisé à 0 sur la deuxième ligne et n'est modifié qu'après le corps de la boucle). Le correctif est simple: l'initialiser à 4 au lieu de 0.

+2

Vous rigolez? «rem» division matérielle pour un diviseur constant de 2? (https://stackoverflow.com/questions/40354978/why-is-this-c-code-faster-than-my-hand-written-assembly-for-testing-the-collat/40355466#40355466). Ou est-ce une pseudo-instruction que l'assembleur va transformer en «AND»? Nous savons que «Bulbs [j-i]» est non négatif. –

+0

@PeterCordes bon commentaire - c'était une réponse peu précipitée. N'a pas écrit suffisamment d'assembleur pour optimiser rapidement (x% 2) comme (x & 0x1), mais c'est assez évident, laissez-moi mettre à jour ma réponse. Mais à la fin, la différence devrait être une seule instruction par rapport à 'rem' de toute façon (div + un mouvement par opposition à un seul et), pas si terrible. – K4rolis

+2

Toutes les instructions ne fonctionnent pas à la même vitesse. Sur x86 moderne, 'div' est environ 30 fois plus long que' and '(1 cycle). Si quoi que ce soit, c'est probablement pire sur MIPS, car les diviseurs de matériel haute performance sont chers (dans la zone des matrices de silicium). Voir la réponse que j'ai liée pour en savoir plus sur la division étant lente, et comment vous devez savoir ce que vous faites pour faire du meilleur code qu'un compilateur. (Mais si vous le faites, vous pouvez souvent.) –