Array e strutture dati in assembly ARM
In questa pagina 5
Array
Un array di elementi di byte occupa byte consecutivi. L'elemento sta all'indirizzo
Per int (4 byte): LDR r0, [r1, r2, LSL #2] legge a[r2] con r1 = indirizzo di a (vedi Istruzioni ARM di accesso alla memoriaLDR e STR per parole, byte e mezze parole con e senza segno; modalità di indirizzamento con offset immediato o registro scalato, pre-indicizzata con write-back e post-indicizzata, con esempi di indirizzo effettivo; caricamento di indirizzi e costanti; LDM e STM.Istruzioni ARM di accesso alla memoria →).
.data
a: .word 3, -1, 7, 2, 5 @ int a[5]
buf: .space 20 @ 20 byte non inizializzati
msg: .asciz "ciao" @ stringa con terminatore 0Somma degli elementi, con indice
LDR r1, =a @ base
MOV r2, #0 @ i
MOV r0, #0 @ somma
ciclo: CMP r2, #5
BGE fine
LDR r3, [r1, r2, LSL #2] @ r3 = a[i]
ADD r0, r0, r3
ADD r2, r2, #1
B ciclo
fine: @ r0 = 3 - 1 + 7 + 2 + 5 = 16Massimo, con puntatore
LDR r1, =a
ADD r2, r1, #20 @ r2 = indirizzo dopo l'ultimo elemento
LDR r0, [r1], #4 @ max = a[0], r1 avanza
ciclo: CMP r1, r2
BHS fine @ confronto tra indirizzi: senza segno
LDR r3, [r1], #4
CMP r3, r0
MOVGT r0, r3
B ciclo
fine: @ r0 = 7Il puntatore post-incrementato evita la moltiplicazione dell'indice: è quello che fa un compilatore con for (p = a; p < a + 5; p++).
Stringhe
Una stringa C è un array di byte terminato da 0. Lunghezza (strlen):
strlen: MOV r1, r0 @ r1 scorre la stringa, r0 = inizio
ciclo: LDRB r2, [r1], #1
CMP r2, #0
BNE ciclo
SUB r0, r1, r0
SUB r0, r0, #1 @ r1 ha superato anche il terminatore
BX lrPer "ciao": il ciclo legge 5 byte, alla fine e il risultato è .
Copia (strcpy(dst, src), dst in r0, src in r1):
copia: LDRB r2, [r1], #1
STRB r2, [r0], #1
CMP r2, #0
BNE copia
BX lrMatrici
Una matrice int m[R][C] è memorizzata per righe: l'elemento sta a
Con C = 3, m[2][1] sta a base + base + 28.
Strutture
I campi di una struct stanno in sequenza, ciascuno allineato alla sua dimensione:
struct punto { char tipo; int x; int y; };| Campo | Offset | Dimensione |
|---|---|---|
tipo |
0 | 1 (+ 3 byte di riempimento) |
x |
4 | 4 |
y |
8 | 4 |
Dimensione totale 12 byte. Con r0 = indirizzo della struct: LDRB r1, [r0] legge tipo, LDR r2, [r0, #4] legge x, STR r3, [r0, #8] scrive y. Un array di struct si scorre con passo 12.
Errori tipici
- Passo di 1 invece di 4 per gli array di
int, o di 4 invece di 1 per le stringhe. - Dimenticare il riempimento per l'allineamento nel calcolo degli offset delle struct.
- Confrontare puntatori con
BGE/BLT(con segno) invece diBHS/BLO.
Versione ripasso
Array e stringhe
- Elemento con elementi da byte: . Per
int:LDR r0, [r1, r2, LSL #2](Istruzioni ARM di accesso alla memoriaLDR e STR per parole, byte e mezze parole con e senza segno; modalità di indirizzamento con offset immediato o registro scalato, pre-indicizzata con write-back e post-indicizzata, con esempi di indirizzo effettivo; caricamento di indirizzi e costanti; LDM e STM.Istruzioni ARM di accesso alla memoria →). Direttive:.word 3, -1, 7, 2, 5,.space 20,.asciz "ciao". - Somma con indice (5 elementi):
CMP r2, #5;BGE fine;LDR r3, [r1, r2, LSL #2];ADD r0, r0, r3;ADD r2, r2, #1;B ciclo. Risultato . - Massimo con puntatore:
LDR r0, [r1], #4(max = a[0]); ciclo conCMP r1, r2(r2 = fine array),BHS fine(indirizzi: senza segno),LDR r3, [r1], #4,CMP r3, r0,MOVGT r0, r3. Risultato 7. - Stringa = byte terminati da 0.
strlen:LDRB r2, [r1], #1;CMP r2, #0;BNE ciclo;SUB r0, r1, r0;SUB r0, r0, #1."ciao": .strcpy:LDRB,STRBcon post-incremento fino al terminatore.
Matrici e strutture
m[R][C]per righe: a ; con ,m[2][1]a base .- Campi di una
structin sequenza, allineati:{ char tipo; int x; int y; }ha offset 0, 4, 8 (3 byte di riempimento) e dimensione 12;LDR r2, [r0, #4]leggex; un array di struct ha passo 12.
Errori tipici: passo 1 invece di 4 (o 4 invece di 1 per le stringhe); dimenticare il riempimento; BGE/BLT sui puntatori invece di BHS/BLO.