Istruzioni ARM di accesso alla memoria
In questa pagina 5
In questa pagina 4
In un'architettura load/store (vedi L'architettura ARMARM a 32 bit come caso di studio: registri r0-r15 con SP, LR e PC, registro di stato CPSR con flag NZCV, modi del processore, architettura load/store, istruzioni condizionate, secondo operando flessibile, Thumb; differenze principali con ARMv8 a 64 bit.L'architettura ARM →) i dati si portano nei registri con una load, si elaborano, e si riportano in memoria con una store.
Load e store
| Istruzione | Effetto |
|---|---|
LDR Rd, [ind] |
carica una parola (4 byte) |
STR Rd, [ind] |
salva una parola |
LDRB / STRB |
byte; LDRB estende con zeri a 32 bit |
LDRSB |
byte con segno, esteso con il segno |
LDRH / STRH |
mezza parola (16 bit), estesa con zeri |
LDRSH |
mezza parola con segno |
Esempio: in memoria all'indirizzo r1 c'è il byte 0xF0. LDRB r0, [r1] → r0 = 0x000000F0 (240); LDRSB r0, [r1] → r0 = 0xFFFFFFF0 (−16). Vedi l'estensione del segno in Rappresentazione dei numeri interi con segnoInteri con segno su n bit: modulo e segno, complemento a 1, complemento a 2 ed eccesso K; intervalli rappresentabili, calcolo dell'opposto, estensione del segno.Rappresentazione dei numeri interi con segno →.
In STR r0, [r1] il primo registro è la sorgente (viene letto), non la destinazione.
Modalità di indirizzamento
Esempi con r1 = 0x1000, r2 = 3:
| Sintassi | Indirizzo effettivo | r1 dopo |
|---|---|---|
[r1] |
0x1000 | invariato |
[r1, #8] |
0x1008 | invariato |
[r1, #-4] |
0x0FFC | invariato |
[r1, r2] |
0x1003 | invariato |
[r1, r2, LSL #2] |
0x1000 + 12 = 0x100C | invariato |
[r1, #4]! (pre-indicizzato con write-back) |
0x1004 | 0x1004 |
[r1], #4 (post-indicizzato) |
0x1000 | 0x1004 |
- L'offset immediato per
LDR/STRdi parola o byte è di 12 bit (±4095). - Pre-indicizzato
!: calcola l'indirizzo, accede, poi aggiorna la base. - Post-indicizzato: accede all'indirizzo della base, poi la aggiorna. Comodo per scorrere un array:
LDR r0, [r1], #4legge l'elemento e fa avanzare il puntatore. LSL #2sull'indice moltiplica per 4: indice di elemento → offset in byte per un array di parole.
Indirizzi e costanti
LDR r0, =etichettacarica l'indirizzo di una variabile (pseudo-istruzione: l'assemblatore mette l'indirizzo in una tabella di costanti vicina al codice e genera unLDRrelativo al PC).ADR r0, etichettacalcola l'indirizzo come PC + offset (solo per etichette vicine).LDR r0, =1000000carica una costante che non entra in un immediato.
Per leggere il contenuto di una variabile servono due passi:
LDR r1, =conta @ r1 = &conta
LDR r0, [r1] @ r0 = conta
ADD r0, r0, #1
STR r0, [r1] @ conta = conta + 1
.data
conta: .word 0Trasferimenti multipli
LDM/STM caricano o salvano una lista di registri in posizioni consecutive. Suffissi: IA (increment after), IB, DA, DB (decrement before).
STMDB sp!, {r4-r6, lr} @ = PUSH {r4-r6, lr}: sp -= 16, salva 4 registri
LDMIA sp!, {r4-r6, pc} @ = POP {r4-r6, pc}: ripristina e ritornaI registri della lista vanno in memoria in ordine di numero: il più basso all'indirizzo più basso. Uso principale: salvare e ripristinare registri nelle funzioni (vedi Stack e chiamata di funzioni in ARMChiamata con BL e ritorno con BX LR; convenzione di chiamata AAPCS (argomenti in r0-r3, risultato in r0, registri da preservare r4-r11); stack discendente pieno con PUSH e POP; record di attivazione; funzioni foglia e non foglia; esempio ricorsivo del fattoriale con evoluzione dello stack.Stack e chiamata di funzioni in ARM →) e copiare blocchi di memoria.
Errori tipici
- Usare
LDR r0, xpensando di ottenere l'indirizzo dix: si ottiene il contenuto (indirizzamento relativo al PC). L'indirizzo èLDR r0, =x. - Scorrere un array di parole con passo 1 invece di 4.
- Leggere un byte con segno con
LDRB.
Versione ripasso
Architettura load/store (L'architettura ARMARM a 32 bit come caso di studio: registri r0-r15 con SP, LR e PC, registro di stato CPSR con flag NZCV, modi del processore, architettura load/store, istruzioni condizionate, secondo operando flessibile, Thumb; differenze principali con ARMv8 a 64 bit.L'architettura ARM →): load, elaborazione, store.
Load e store
LDR/STR parola; LDRB/STRB byte (esteso con zeri); LDRSB byte con segno; LDRH/STRH mezza parola; LDRSH con segno. Con byte 0xF0: LDRB 0x000000F0 (240); LDRSB 0xFFFFFFF0 (), vedi Rappresentazione dei numeri interi con segnoInteri con segno su n bit: modulo e segno, complemento a 1, complemento a 2 ed eccesso K; intervalli rappresentabili, calcolo dell'opposto, estensione del segno.Rappresentazione dei numeri interi con segno →. In STR r0,[r1] il primo registro è la sorgente.
Indirizzamento (r1 = 0x1000, r2 = 3)
[r1]0x1000;[r1,#8]0x1008;[r1,#-4]0x0FFC;[r1,r2]0x1003;[r1,r2,LSL #2]0x100C.r1invariato.- Pre-indicizzato
[r1,#4]!: accede a 0x1004 e aggiornar1 = 0x1004. - Post-indicizzato
[r1],#4: accede a 0x1000, poir1 = 0x1004(scorrere un array). - Offset immediato di 12 bit ();
LSL #2trasforma l'indice in offset in byte.
Indirizzi e costanti
LDR r0,=etichetta carica l'indirizzo (pseudo-istruzione con tabella di costanti vicina); ADR calcola PC + offset (etichette vicine); LDR r0,=1000000 carica costanti grandi. Per il contenuto servono due passi: LDR r1,=conta; LDR r0,[r1]; ADD r0,r0,#1; STR r0,[r1].
Trasferimenti multipli
LDM/STM con IA, IB, DA, DB: STMDB sp!,{r4-r6,lr} PUSH (); LDMIA sp!,{r4-r6,pc} POP. Il registro più basso va all'indirizzo più basso (Stack e chiamata di funzioni in ARMChiamata con BL e ritorno con BX LR; convenzione di chiamata AAPCS (argomenti in r0-r3, risultato in r0, registri da preservare r4-r11); stack discendente pieno con PUSH e POP; record di attivazione; funzioni foglia e non foglia; esempio ricorsivo del fattoriale con evoluzione dello stack.Stack e chiamata di funzioni in ARM →).
Errori tipici: LDR r0, x dà il contenuto, l'indirizzo è LDR r0, =x; passo 1 invece di 4 per le parole; LDRB per un byte con segno.