2016-08-31 3 views
0
  • Problème:

J'essaie d'obtenir le EIET EQ ie 'If-Then-Else-choses égales par ailleurs' bloc de travailler lorsque R6 == 0, avec ALORS ramification dans l'étiquette END mais l'assembleur appelé à une erreur sur la ligne: BEQ FINassemblage ARMv7-M utilisation de EIET

  • info programme:

Je fais un programme qui est en pertinence avec l'optimisation. J'utilise une descente de gradient pour converger vers le point où gradient est 0 pour trouver la solution x * qui minimise une fonction f (x). J'utilise le langage C pour appeler une fonction d'assemblage qui est ce programme ici.

Voici mon programme où l'erreur est :

 CMP R6, #0   @ Compare f'(x) with 0 
     ITEE EQ    @ If R6 == 0, Then-Else-Else 
     BEQ END    @ Calls END label if equal 
     SUBNE R0, R6  @ Change R0(x) in the opp direction of gradient to get lower value of f(x) if not equal 
     BNE optimize  @ Branch to optimize if not equal 

Ceci est mon premier programme de montage en utilisant le NXP LPC1769 pour un travail scolaire. Faites-moi savoir ce que je manque ou j'ai mal fait. Je vous remercie!

Voici mon programme complet:

.syntax unified 
.cpu cortex-m3 
.thumb 
.align 2 
.global optimize 
.thumb_func 

optimize: 
@ Write optimization function in assembly language here 

     MOV R5, INLAMBDA @ R5 holds value of inverse lambda(10) ie to eliminate floating point 
     LDR R6, #2   @ Load R6 with value '2' ie constant of f'(x) 
     MUL R6, R1, R6  @ Multiply R6(2) with R1(a) & store to R6(results) 
     MLA R6, R6, R0, R2 @ Multiply R6(results) with R0(x) & sum with R2(b) to get f'(x). Store & update results to R6 
     SDIV R6, R5   @ Divide R6(results) by R5(1/lambda) to get f'(x) * lambda 

     CMP R6, #0   @ Compare f'(x) with 0 
     ITEE EQ    @ If R6 == 0, Then-Else-Else 
     BEQ END    @ Calls END label if equal 
     SUBNE R0, R6  @ Change R0(x) in the opp direction of gradient to get lower value of f(x) if not equal 
     BNE optimize  @ Branch to optimize if not equal 

@ End label 
END: 

BX LR 

@ Define constant values 
CONST: .word 123 
INLAMBDA: .word 10  @ Inverse lambda 1/lambda(0.1) is 10 
+0

Le message d'erreur vous dit exactement ce que le problème est: 'Erreur: la branche doit être la dernière instruction dans le bloc IT - 'beq END'' –

+0

A moins que ce ne soit, disons, "erreur: A1603E: cette instruction à l'intérieur du bloc IT a des résultats UNPREDICTABLE", ce qui est plutôt moins clair, ou peut-être un autre assembleur encore moins utile. De toute façon, il est toujours bon d'inclure le message d'erreur _specific_ dans la question elle-même, notamment parce que la première chose que beaucoup de gens font avec une erreur inconnue est de le coller dans un moteur de recherche pour voir ce qui se passe. – Notlikethat

Répondre

2

Le problème est que BEQ END est dans le milieu du bloc informatique. Pour citer some documentation for IT:

A branch or any instruction that modifies the PC is only permitted in an IT block if it is the last instruction in the block.

Cela dit, parce c'est une branche, le « autre » est implicite de toute façon - si vous prenez la branche, vous ne serez pas exécuter les instructions suivantes en raison d'être ailleurs, et si vous ne le prenez pas, vous n'avez pas d'autre choix que de les exécuter, il n'est donc pas nécessaire qu'ils soient explicitement conditionnels. En fait, vous n'avez même pas besoin de IT non plus, puisque B<cond> a un codage d'instruction de pouce approprié dans son propre droit. Mais alors vous n'avez même pas besoin de , parce que vous faites une courte branche en avant basée sur un registre étant zéro, et il y a une instruction de comparaison et de branchement spécifique Thumb seulement pour faire exactement cela!

En d'autres termes, votre premier extrait 5 en ligne peut être exprimée simplement:

CBZ R6, END 
SUB R0, R6 
B optimize 
+0

Je n'ai jamais vu 'CBZ' avant. C'est une petite instruction astucieuse. – rjp