Frammento ARM Assembly per STM32

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2872
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Frammento ARM Assembly per STM32

Messaggio da DoctorStrange »

Buongiorno a tutti,

Io programmo un microcontrollore della ST Microelectronics in Assembly nativo. In particolare il controller che uso si chiama STM32F103RB. Il suo Reference Manual si trova qui.

Ora, andando a pagina 171 di questo manuale, si trova uno dei suoi registri interni che si chiama GPIO_CRL. Lo scopo della routine che ho realizzato, è quello di fare in modo che i bit da 31 a -> 24 siano impostati in questo modo: 1 0 0 1 1 0 0 1.

Una condizione però indispensabile è che, mentre questi otto bit vanno impostati con quel pattern, tutti gli altri bit dello stesso registro devono rimanere nello stato precedente che suppongo essere sconosciuto, e devono rimanere identici, anche dopo che io ho impostato i bit che mi interessano.

Per farlo ho sviluppato questa routine, e vorrei sapere se nella comunity c'è qualcuno con un pò di esperienza in ARM Assembly che mi possa dare una controllata a questo frammento di codice:

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
mov       r2,#0x06
lsl            r2,r2,#0x018
mvn.w    r2,r2
and         r2,r2,r1
mov        r3,#0x018
orr           r2,r2,r3
str           r2,[r0]
@In r0 c'è l'indirizzo del registro GPIO_CRL
Sò che è una richiesta un pò strana e che magari l'ARM assembly è un linguaggio molto di nicchia, ma confido che esista qualche irriducibile come me :)

Grazie mille.
Avatar utente
Eresia
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: venerdì 30 giugno 2006, 1:20
Distribuzione: gentoo
Sesso: Maschile

Re: Frammento ARM Assembly per STM32

Messaggio da Eresia »

scusa la domanda non sono molto ferrato nell'assembly [le uniche mie competenze derivano da vari debug], ma perchè usi mvn.w e non mvn o mvnne ?
emerge --auD --oneshot life/lucky-*
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2872
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: Frammento ARM Assembly per STM32

Messaggio da DoctorStrange »

Eresia ha scritto: ma perchè usi mvn.w e non mvn o mvnne ?
mvn.w Significa "Move NOT" ed il ".w" alla fine specifica che stò definendo una word, ovvero una variabile a sedici bit, nonostante il core sia a 32, mi serve per allineare questa not a tutte le altre istruzioni. Questa particolare istruzione serve ad invertire lo stato di tutti i bit definiti in quel registro.

mvn (senza il ".w") avrebbe potuto creare qualche problema, dal momento che il core del processore è a 32 bit, ma quesl particolare registro è definito a sedici bit, quindi mi serviva specificare un'istruzione che fosse minore del normale standard a 32 bit.

mvnne non mi risulta essere un'istruzione esistente. Forse deriva da qualche altro tipo di linguaggio, o per qualche altro tipo di micro controllore?
Avatar utente
Eresia
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 362
Iscrizione: venerdì 30 giugno 2006, 1:20
Distribuzione: gentoo
Sesso: Maschile

Re: Frammento ARM Assembly per STM32

Messaggio da Eresia »

perfetto, grazie per l'appunto!
http://www.keil.com/support/man/docs/ar ... 882734.htm

però ripeto, non sono un programmatore assembly, mi limito a disassemblare parti di programmi con gdb
emerge --auD --oneshot life/lucky-*
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: Frammento ARM Assembly per STM32

Messaggio da melfnt »

DoctorStrange [url=https://forum.ubuntu-it.org/viewtopic.php?p=5105100#p5105100][img]https://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Buongiorno a tutti,

Io programmo un microcontrollore della ST Microelectronics in Assembly nativo. In particolare il controller che uso si chiama STM32F103RB. Il suo Reference Manual si trova qui.

Ora, andando a pagina 171 di questo manuale, si trova uno dei suoi registri interni che si chiama GPIO_CRL. Lo scopo della routine che ho realizzato, è quello di fare in modo che i bit da 31 a -> 24 siano impostati in questo modo: 1 0 0 1 1 0 0 1.

Una condizione però indispensabile è che, mentre questi otto bit vanno impostati con quel pattern, tutti gli altri bit dello stesso registro devono rimanere nello stato precedente che suppongo essere sconosciuto, e devono rimanere identici, anche dopo che io ho impostato i bit che mi interessano.

Per farlo ho sviluppato questa routine, e vorrei sapere se nella comunity c'è qualcuno con un pò di esperienza in ARM Assembly che mi possa dare una controllata a questo frammento di codice:

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
mov       r2,#0x06
lsl            r2,r2,#0x018
mvn.w    r2,r2
and         r2,r2,r1
mov        r3,#0x018
orr           r2,r2,r3
str           r2,[r0]
@In r0 c'è l'indirizzo del registro GPIO_CRL
Sò che è una richiesta un pò strana e che magari l'ARM assembly è un linguaggio molto di nicchia, ma confido che esista qualche irriducibile come me :)

Grazie mille.
Ciao!
Nel documento che hai linkato non c'è l'instruction set, quindi risulta abbastanza difficile aiutarti. In particolare, ci sono alcune istruzioni che non capisco cosa facciano:
lsl (è uno shift a sinistra?), mvn.w (già chiarito nel precedente post), orr.

Comunque il tuo codice mi sembra fin troppo complicato per lo scopo che devi raggiungere, io lo avrei fatto usando due maschere di bit.
Probabilmente lo sai già e le avrai già usate in altri contesti: l'osservazione principale è che se fai l'AND bit a bit fra il valore di un registro e una maschera composta da zeri e uni, il risultato avrà zero nelle posizioni in corrispondenza degli zeri nella maschera e il valore del registro originale in corrispondenza degli uni della maschera. Similmente, se fai l'OR bit a bit fra il valore di un registro e una maschera composta da zeri e uni, il risultato avrà uno nelle posizioni in corrispondenza degli uni della maschera e il valore del registro originale in corrispondenza degli zeri nella maschera.
Questo fatto è facilmente verificabile: qualsiasi sia il valore binario X,
1 AND X = X
0 AND X = 0
1 OR X = 1
0 OR X = X

Sfruttando questo fatto, bastano un AND e un OR con due maschere appropriate per riuscire a settare tutti i bit che ti servono in un registro:

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, #MASCHERA_AND
or          r1, r1, #MASCHERA_OR
str         r1,[r0]
@In r0 c'è l'indirizzo del registro GPIO_CRL
Esercizio: trova i valori corretti di MASCHERA_AND e MASCHERA_OR affinché i bit da 24 a 31 vengano settati come vuoi.

Soluzione:
Spoiler
Mostra
assumendo che il bit 31 sia quello meno significativo, altrimenti devi ribaltare le maschere
MASCHERA_AND = #0b11111111111111111111111111001001
MASCHERA_OR = #0b00000000000000000000000001001001

Quindi il codice diventa:

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, #0b11111111111111111111111111001001
or          r1, r1, #0b00000000000000000000000001001001
str         r1,[r0]
@In r0 c'è l'indirizzo del registro GPIO_CRL
Se non puoi usare le costanti in binario, trasforma quei due numeri in esadecimale :)
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2872
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: Frammento ARM Assembly per STM32

Messaggio da DoctorStrange »

Quelle che ho fatto sono esattamente due maschere. Una di and per azzerare ed una di or per settare.

Sono in totale sei istruzioni. 100 nano secondi per completare l'intera procedura. Non credo di poter pretendere di meglio, per in controllore da due euro. Giusto?

La tua soluzione non l'ho studiata ma è di sicuro errata, perchè usi variabili a 32 bit, mentre quel registro è a 16.

Per questo motivo mi sono servito di una shift e di una move-not. Per non appestare il compilatore di una sfilza di uni e zero.
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: Frammento ARM Assembly per STM32

Messaggio da melfnt »

Ciao!
DoctorStrange [url=https://forum.ubuntu-it.org/viewtopic.php?p=5105499#p5105499][img]https://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Quelle che ho fatto sono esattamente due maschere. Una di and per azzerare ed una di or per settare.
melfnt ha scritto: Ciao!
Nel documento che hai linkato non c'è l'instruction set, quindi risulta abbastanza difficile aiutarti. In particolare, ci sono alcune istruzioni che non capisco cosa facciano:
lsl (è uno shift a sinistra?), mvn.w (già chiarito nel precedente post), orr.
Se mi rispondi anche a questo provo a controllare anch'io il tuo frammento (:

Sono in totale sei istruzioni. 100 nano secondi per completare l'intera procedura. Non credo di poter pretendere di meglio, per in controllore da due euro. Giusto?
Completamente in disaccordo. Se sei un programmatore assembler e puoi fare una cosa in due istruzioni, perché farla con sei?
Non è solo questione di quanto tempo ci mettono ad essere eseguite, ma anche di quanto è lungo il codice, che influisce sui cache fault.

La tua soluzione non l'ho studiata ma è di sicuro errata, perchè usi variabili a 32 bit, mentre quel registro è a 16.
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? In questo secondo caso, perché parli di bit da 24 a 31 se i bit sono 16?

E ancora, nell'istruzione str r2,[r0] stai spostando il contenuto di r2 in GPIO_CRL: se uno dei due è a 32 bit e l'altro a 16, dev'essere definito il modo in cui i 32 bit vengono spostati in un registro a 16 bit (per esempio: vengono usati solo i 16 bit meno significativi).
Altrimenti, se sono entrambi registri a 16 bit puoi semplicemente usare maschere a 16 bit, troncando le mie.

Per questo motivo mi sono servito di una shift e di una move-not. Per non appestare il compilatore di una sfilza di uni e zero.
Qui non ti seguo: cosa intendi con "appestare"?

:)
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2872
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: Frammento ARM Assembly per STM32

Messaggio da DoctorStrange »

melfnt ha scritto: Se mi rispondi anche a questo provo a controllare anch'io il tuo frammento (:
L'assembly è un linguaggio di programmazione, quello che ho postato è un Reference Manual, dunque se vuoi le specvifiche dell'assembly, devi cercare le specifiche del linguaggio.
melfnt ha scritto:
Completamente in disaccordo. Se sei un programmatore assembler e puoi fare una cosa in due istruzioni, perché farla con sei?
Non è solo questione di quanto tempo ci mettono ad essere eseguite, ma anche di quanto è lungo il codice, che influisce sui cache fault.
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.

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.
melfnt ha scritto: Qui non ti seguo: cosa intendi con "appestare"?
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.
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: Frammento ARM Assembly per STM32

Messaggio da melfnt »

DoctorStrange [url=https://forum.ubuntu-it.org/viewtopic.php?p=5105586#p5105586][img]https://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:
melfnt ha scritto: Se mi rispondi anche a questo provo a controllare anch'io il tuo frammento (:

L'assembly è un linguaggio di programmazione, quello che ho postato è un Reference Manual, dunque se vuoi le specvifiche dell'assembly, devi cercare le specifiche del linguaggio.
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 :D
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:

Codice: Seleziona tutto

mov    $0x19,%edx
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.
Avatar utente
runblade
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 396
Iscrizione: martedì 3 aprile 2007, 14:28
Distribuzione: 16 Valvole monoalbero in testa.
Località: Soave

Re: Frammento ARM Assembly per STM32

Messaggio da runblade »

Ora non so che sistema di sviluppo utilizzi, ma compilarlo e debuggarlo sul target mediante jtag (o SWD) direttamente sul core del micro? :(

E pensare che ARM con questi core M3 (e in generale con tutti i suoi 32bit) ha cercato in tutti i modi di svincolare i programmatori di microcontrollori dall'utilizzo dell'assembly...Manco aveste un uPD75pxx o un MCS51 con 4K di ROM :muro:
-Pensare che i videogames possano aver condizionato le menti delle persone è come se chi avesse giocato a pac-man ora ce lo ritovassimo in un ambiente buio, al suono di musica tecno, che gira attorno la pista e continuamente si impasticca...
-Non discutere mai con un idiota: ti trascina al suo livello e poi ti batte con l'esperienza
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: Frammento ARM Assembly per STM32

Messaggio da melfnt »

runblade [url=https://forum.ubuntu-it.org/viewtopic.php?p=5105611#p5105611][img]https://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Ora non so che sistema di sviluppo utilizzi, ma compilarlo e debuggarlo sul target mediante jtag (o SWD) direttamente sul core del micro? :(

E pensare che ARM con questi core M3 (e in generale con tutti i suoi 32bit) ha cercato in tutti i modi di svincolare i programmatori di microcontrollori dall'utilizzo dell'assembly...Manco aveste un uPD75pxx o un MCS51 con 4K di ROM :muro:
In una situazione normale ti darei ragione, in questo caso ci sono ben due motivi per cui un programmatore lo vorrebbe scrivere direttamente in assembler:

1) l'efficienza su cui mi sono già espresso prima.
2) Se ci fosse un modo ad alto livello di impostare i pin GPIO probabilmente sarebbe una chiamata di libreria a cui va specificata una maschera di bit, allora tanto vale farlo in assembler direttamente.
iliozac
Prode Principiante
Messaggi: 1
Iscrizione: domenica 10 maggio 2020, 13:20

Re: Frammento ARM Assembly per STM32

Messaggio da iliozac »

ho programmato in assembler per vent'anni ma confesso che non mi sarebbe mai venuta in mente una soluzione come la tua per fare una semplice maschera su 16 o 32 bit...
Condivido quanto scritto da Melfnt e scriverei praticamente lo stesso codice che propone lui. Anch'io utilizzo spesso l'assembly quando devo rendere performante un pezzo di codice o poter controllare le istruzioni a livello di singolo ciclo macchina (dato che lavoro su audio e video), e a volte per riuscirci devo scrivere e duplicare interi pezzi di codice occupando memoria pur di non utilizzare istruzioni di salti condizionati che sono meno gestibili a livello di timing.
E' ovvio però che ognuno scrive il codice in base al risultato che vuole ottenere... io però non ho capito bene qual'è quello che vuoi ottenere tu
Avatar utente
runblade
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 396
Iscrizione: martedì 3 aprile 2007, 14:28
Distribuzione: 16 Valvole monoalbero in testa.
Località: Soave

Re: Frammento ARM Assembly per STM32

Messaggio da runblade »

Ho programmato dai MC68000 Z80, uPD78xxx, AVR, etc. in assembly e li per fare qualcosa era un must.
Ma sulla famiglia stm32Xxx dove la X va dallo 0 al 7 e passa dal 48Mhz ai circa 300Mhz e si usano loro tools (Mxcube) loro librerie, mantenere le librerie basso livello standard è funzionale alla portabilità del codice senza troppi sbattimenti,alle diverse serie di famiglie...
Poi ognuno è libero di fare ciò che vuole e lo ammetto: per l'uso della piattaforma ARM non mi sono/voglio "smazzare" a imparare a fondo l'assembler, è già una impresa usare i tools di sviluppo dedicati... :)
-Pensare che i videogames possano aver condizionato le menti delle persone è come se chi avesse giocato a pac-man ora ce lo ritovassimo in un ambiente buio, al suono di musica tecno, che gira attorno la pista e continuamente si impasticca...
-Non discutere mai con un idiota: ti trascina al suo livello e poi ti batte con l'esperienza
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2872
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: Frammento ARM Assembly per STM32

Messaggio da DoctorStrange »

Ringrazio tutti delle risposte.

Quella che ho usato nel primo post è una tecnica che uso costantemente. Ho realizzato due maschere per eseguire operazioni bitwise sul registro CRL.

Il motivo per questa complicazione è, prima di tutto perchè cerco sempre di usare costanti ad otto bit, e poi una serie finita di rotazioni o negazioni, per generare la maschera definitiva.
Se non facessi in questo modo, dal momento che devo operare sui bit piu significativi, avrei dovuto dichiarare una "Litteral pool" per appoggiare le costanti a 32 bit, e tendo sempre a tenere ordinata la memoria RAM per quanto possibile, quindi tutte le pool sono messe in automatico alla fine del codice programma.

Mi posso permettere di allungare il codice di qualche istruzione in piu, perchè non ho necessità dell'ultimo nanosecondo, soprattutto in una routine preposta alla configurazione di un registro.

Finora ha sempre funzionato tutto benissimo.
AleCpm
Prode Principiante
Messaggi: 3
Iscrizione: sabato 16 maggio 2020, 14:06

Re: Frammento ARM Assembly per STM32

Messaggio da AleCpm »

ciao a tutti

secondo me potresti utilizzare efficacemente l' istruzione BFI (bit field insert)

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
mov        r2,#0x99      
bfi        r1,r2,#24,#8
str        r1,[r0]
@In r0 c'è l'indirizzo del registro GPIO_CRL
mi sembra abbastanza efficiente e pulito :D
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2872
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: Frammento ARM Assembly per STM32

Messaggio da DoctorStrange »

L'istruzione di cui parli non è diversa dalle altre, nel senso che è "mutuata" da linguaggi ad alto livelòlo.

Con questo voglio dire che, a livello di assembler (inteso proprio come assemblaggio del codice), questa viene sempre tradotta in automatico in una seria finita di rotazioni e negazioni, per ottenere la medesima maschera.

A questo punto preferisco essere io a predisporre queste stesse rotazioni o negazioni, in modo da mantenere il controllo sul flusso del programma.
AleCpm
Prode Principiante
Messaggi: 3
Iscrizione: sabato 16 maggio 2020, 14:06

Re: Frammento ARM Assembly per STM32

Messaggio da AleCpm »

No scusami se ti contraddico ma l' istruzione fa parte del set di istruzioni del Cortex M3 e non viene assolutamenta tradotta, ha un proprio codice operativo e viene eseguita in un ciclo macchina. Vedi per dettagli pagina 90 del PM0056 Programming manual-STM32F10xxx Cortex-M3 programming manual scaricabile dal sito ST.com
AleCpm
Prode Principiante
Messaggi: 3
Iscrizione: sabato 16 maggio 2020, 14:06

Re: Frammento ARM Assembly per STM32

Messaggio da AleCpm »

La mia comunque non vuole essere una critica ma un consiglio a studiare più a fondo il set di istruzioni, perchè secondo me una conoscenza dell' assembly non fa mai male anche se siamo oggi abituati ad utilizzare solo linguaggi ad alto livello. Infatti alcune volte per il debug di problemi apparentemente incomprensibili è indispensabile analizzare il disassembly del codice.
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 14 ospiti