Forum: Mikrocontroller und Digitale Elektronik ARM7: unaligned memory access


von Peter (Gast)


Lesenswert?

Hallo NG,

nehmen wir mal an, ich habe im Speicher folgendes:

ALIGN 4
memory:
00 | 4c | 31 | ea | 00 | 00

dann kann ich ja mit
ldr r8, [memory]
32 Bit ins Register laden.

mit

ldr r8, [memory + 1]
funktioniert das nicht, da das ja ein "unaligned access" ist...

Ich könnte (mach ich bisher) das Ganze mit ldrb machen und mir dann die 
Bytes über mehrere Befehle hinweg zusammensammeln. Gibts da auch ne 
schönere Methode, um sowas zu machen?

Vielen Dank und viele Grüße,
Peter

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Peter schrieb:
> Ich könnte (mach ich bisher) das Ganze mit ldrb machen und mir dann die
> Bytes über mehrere Befehle hinweg zusammensammeln. Gibts da auch ne
> schönere Methode, um sowas zu machen?

Nein. Erst neuere ARM Prozessoren unterstützen unaligned access.

--
Marcus

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Korrektur. Vorausgesetzt unaligned access löst keinen data abort aus 
(erst ab v5TE konfigurierbar), kannst Du die Daten möglicherweise 
geringfügig schneller laden, indem Du folgendes verwendest:
1
;; int load_word((__packed int) *ptr);
2
load_word PROC
3
4
ptr     RN 0
5
word    RN 0
6
lower   RN 2
7
upper   RN 0
8
align   RN 1
9
10
        ;; check alignment
11
        ANDS    align, ptr, #0x3
12
        ;; if aligned
13
        ;;   load word from address and return
14
        LDREQ   word, [ptr]
15
        BXEQ    lr
16
17
        LSL     align, #3 ; convert align into shift value
18
        MVN     mask, #0
19
20
        ;; else
21
        ;;   load rotated word from word address
22
        ;;   and mask top
23
        LDR     lower, [ptr]
24
        AND     lower, mask, LSR align
25
        
26
        ;;   load rotated word from word address + 4
27
        ;;   mask, and combine both words
28
        LDR     upper, [ptr, #4]
29
        AND     upper, mask, LSL align
30
        ORR     word, lower, upper
31
        BX      lr
32
        ENDP

(ungetestet, da ich gerade Probleme mit dem Lizenzserver habe)

Der Code basiert auf einem in der ARM Architektur definierten Verhalten 
bei unaligned access.

Gruß
Marcus

von Peter P. (uncle-sam7)


Lesenswert?

Hallo Marcus,

bei mir gehts eigentlich immer um max. 2 Bytes. Momentan löse ich das 
so:

abs:  // get address for #$xxxx into r5
  ldrb r4, [r8, #1]
  ldrb r5, [r8, #2]
  add r5, r4, r5, lsl #8
  mov pc, r14

r8 ist in diesem Fall dann "pc" des 6502. In "pc"+1 und "pc"+2 steckt 
die 16 Bit Adresse zum Opcode an "pc".

Gruß,
Peter

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Peter Pippinger schrieb:
> bei mir gehts eigentlich immer um max. 2 Bytes.

Na dann mach' Dir keinen Stress.

> Momentan löse ich das so:
> [...]

Was ist den daran unelegant?

--
Marcus

von Peter P. (uncle-sam7)


Lesenswert?

> Was ist den daran unelegant?
...weiss auch noch nicht...

Bin noch recht unerfahren mit ARM7 Assembler. Und die Emulation des 6502 
macht eigentlich nicht viel. Deswegen würde ich alles so kurz wie 
möglich halten. Hab auch nur den Software-Debugger von der IAR 
Workbench, um das Programm schrittweise durchzugehen.

Was ich eigentlich noch optimierbar sehe:

Die Auflösung der Adresse nicht als Subroutine zu machen, sondern als 
Makro. Würde einen BL und den dazugehörigen Rücksprung weniger 
ergeben...

MfG
Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.