Salta al contenuto
Note per Studenti Array e strutture dati in assembly ARM

Array e strutture dati in assembly ARM

In questa pagina 5

Array

Un array di nn elementi di ss byte occupa n⋅sn \cdot s byte consecutivi. L'elemento ii sta all'indirizzo

base+i⋅s\text{base} + i \cdot s

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 →).

armasm
        .data
a:      .word 3, -1, 7, 2, 5      @ int a[5]
buf:    .space 20                 @ 20 byte non inizializzati
msg:    .asciz "ciao"             @ stringa con terminatore 0

Somma degli elementi, con indice

armasm
        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 = 16

Massimo, con puntatore

armasm
        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 = 7

Il 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):

armasm
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    lr

Per "ciao": il ciclo legge 5 byte, alla fine r1=r0+5r1 = r0 + 5 e il risultato è 5−1=45 - 1 = 4.

Copia (strcpy(dst, src), dst in r0, src in r1):

armasm
copia:  LDRB r2, [r1], #1
        STRB r2, [r0], #1
        CMP  r2, #0
        BNE  copia
        BX   lr

Matrici

Una matrice int m[R][C] è memorizzata per righe: l'elemento (i,j)(i, j) sta a

base+(i⋅C+j)⋅4\text{base} + (i \cdot C + j) \cdot 4

Con C = 3, m[2][1] sta a base + (2⋅3+1)⋅4=(2 \cdot 3 + 1) \cdot 4 = base + 28.

Strutture

I campi di una struct stanno in sequenza, ciascuno allineato alla sua dimensione:

c
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 di BHS/BLO.

Versione ripasso

Array e stringhe

Matrici e strutture

  • m[R][C] per righe: (i,j)(i, j) a base+(i⋅C+j)⋅4\text{base} + (i \cdot C + j) \cdot 4; con C=3C = 3, m[2][1] a base +28+ 28.
  • Campi di una struct in sequenza, allineati: { char tipo; int x; int y; } ha offset 0, 4, 8 (3 byte di riempimento) e dimensione 12; LDR r2, [r0, #4] legge x; 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.

Esercizi su questo argomento

Teoria collegata