Sì, questo l'avevo capito, non stavo criticando la tua risposta. Mi sembra semplicemente molto strano che non ci siano le specifiche dell'assembler in quel manuale.
La spasmodica ricerca di efficienza andando a pistolare nei codici per renderli più rapidi di cento nano secondi, mi sembra un'inutilità. Anche se sviluppo in assembly non mi faccio problemi a rendere il codice un pò più chiaro, rendendolo un pò più prolisso, a costo di dover rallentare di qualche nano secondo l'istruzione.
Ancora una volta, il mio punto di vista è completamente diverso dal tuo: nei linguaggi di programmazione ad alto livello è ragionevole ricercare chiarezza e manutenibilità del codice, ma solo perché a fare le ottimizzazioni ci pensa il compilatore (e ti assicuro che il codice assembler generato dal compilatore è veramente veramente uno schifo, vedi sotto).
Se invece programmi direttamente in assembler, vuol dire o che stai scrivendo tu il compilatore (non è questo il caso) o che hai dei requisiti di efficienza, e in questo caso la la comprensibilità passa in ultimo piano. Fra l'altro non sono molto sicuro che il tuo codice sia più chiaro del mio.
melfnt ha scritto:
Ho visto che nella tua prima risposta hai parlato di registri a 16 bit ma c'è una cosa che non mi è chiara: quale registro è a 16 bit? r2 oppure GPIO_CRL?
Logicamente è GPIO_CRL a sedici bit, come scritto sul Reference Manual.
melfnt ha scritto:
In questo secondo caso, perché parli di bit da 24 a 31 se i bit sono 16?
Qui in effetti hai ragione tu. E' stato un mio errore. Il registro di destinazione è a sedici bit.
Allora puoi usare costanti binarie a 16 bit, e magari un registro general purpose a 16 bit per fare l'AND e l'OR:
Codice: Seleziona tutto
@Presupposto = nel registro r1 leggo lo stato attuale del registro GPIO_CRL, prima di impostare i miei bit. Quindi R1=Stato del registro GPIO_CRL
and r1, r1, #0b1111111111001001
or r1, r1, #0b0000000001001001
str r1,[r0]
@In r0 c'è l'indirizzo del registro GPIO_CRL
Scrivere costanti numeriche composte da interminabili stringhe di uni e di zeri rende il codice poco leggibile e poco portabile. Questo vuol dire che, impiegando notazioni esadecimali ed istruzioni di shisfting, e di inversione (move-not) aumentano ereditarietà, e polimorfismo nel codice. Quindi evito di dichiarare maschere bitwise con interminabili sequenze binarie.
Sulla leggibilità mi sono già espresso prima.
Sulla portabilità mi sembra una battaglia contro i mulini a vento: stai scrivendo in assembler
Il tuo codice sorgente viene letto dall'assemblatore e le istruzioni vengono trasformate in codice macchina in corrispondenza un a uno con quelle scritte in assembler mnemonico, non vedo quindi come un codice di questo tipo possa essere portabile.
I termini
ereditarietà e
polimorfismo mi sembrano estremamente fuori luogo in questo contesto: sono concetti che si applicano ai linguaggi di programmazione ad alto livello e che poco hanno a che fare con l'assembler. Non so se li hai tirati in ballo solo per darti un tono mostrando che conosci questi termini, spero di no, in caso contrario per favore spiegati meglio.
Bonus:
Mi trovi d'accordo sul fatto che un codice ad alto livello (C) di questo tipo :
Codice: Seleziona tutto
#include <stdio.h>
int main ()
{
int a = 5;
a = a+3;
a = a+17;
printf ("%d",a);
return 0;
}
talvolta è più leggibile dell'equivalente:
Codice: Seleziona tutto
#include <stdio.h>
int main ()
{
int a = 25;
printf ("%d",a);
return 0;
}
Soprattutto se i numeri 5, 3, 17 hanno un qualche significato semantico nel contesto o se sono altre variabili. La portabilità del codice non è influenzata da quale delle due versioni viene utilizzata, e in ogni caso, abilitando l'opzione di ottimizzazione di gcc, in entrambi i codici la parte che assegna la variabile a viene compilata con questa istruzione assembler:
Quindi, per me la regola d'oro quando si tratta di maschere (e di costanti in generale): il linguaggio ad alto livello deve essere il più chiaro possibile, l'assembler il più performante possibile.