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
Definizione (istruzioni LDR e STR)
Istruzione Effetto LDR Rd, [ind]carica una parola (4 byte) STR Rd, [ind]salva una parola LDRB/STRBbyte; LDRBestende con zeri a 32 bitLDRSBbyte con segno, esteso con il segno LDRH/STRHmezza parola (16 bit), estesa con zeri LDRSHmezza parola con segno
Esempio. Se il byte in memoria è 0xF0: LDRB r0, [r1] dà r0=0x000000F0 e LDRSB r0, [r1] dà r0=0xFFFFFFF0.
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:
Definizione (modalità di indirizzamento di LDR e STR)
Sintassi Indirizzo effettivo r1dopo[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.
Esempio. Con r1=0x1000: LDR r0, [r1, #4]! legge a 0x1004 e lascia r1=0x1004; LDR r0, [r1], #4 legge a 0x1000 e lascia r1=0x1004.
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
Definizione (trasferimenti multipli LDM e STM).
LDM/STMcaricano o salvano una lista di registri in posizioni consecutive. Suffissi: IA (increment after), IB, DA, DB (decrement before).
Esempio. STMDB sp!, {r4-r6, lr} salva registri e sottrae da sp.
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.