Forum: Mikrocontroller und Digitale Elektronik STM32 Daten kopieren Problem


von Michael P. (protactinium)


Lesenswert?

Hallo zusammen,

ich versuche in meinem Programm Daten in ein Array zu kopieren. Das löst 
jedoch einen "Hard Fault" aus und die CPU bleibt stehen.
Ich verwende einen STM32F030R8 und programmiere mit Truestudio.
Mein Code sieht wie folgt aus:
1
void MeineFunktion(uint32_t Data)
2
{
3
    uint8_t DataArray[11];
4
    
5
    *(uint32_t*)&DataArray[2] = Data;
6
    *(uint32_t*)&DataArray[7] = *(uint32_t*)&DataArray[2];
7
8
    DataArray[6] = 0x09;
9
10
    /* weitere Verarbeitung */
11
}

Nu meine ganz einfache Frage:

Was mache ich falsch?

Danke für eure Hilfe.

Michael

von Karl (Gast)


Lesenswert?

Das  Alignment stimmt ziemlich sicher nicht.  Cortex m können auf 32 Bit 
Variablen nur an Adressen zugreifen die durch 4 ohne Rest teilbar sind*.

*afaik gibt es einen Modus des kerns der das toleriert. Wird aber selten 
verwendet.

von Nop (Gast)


Lesenswert?

Michael P. schrieb:

> void MeineFunktion(uint32_t Data)

Das ist ein 32-bit-Integer.

>     uint8_t DataArray[11];

Da sollen 8-bit-Integer rein, und demzufolge ist das nicht aligned.

>     *(uint32_t*)&DataArray[2] = Data;

Dieses Pointergecaste wird wohl auf eine unaligned-Adresse kommen (das 
bewirkt den Hardfault) und ist außerdem wegen Pointer-Aliasing schon 
nach C-Standard undefiniertes Verhalten.

von asdf (Gast)


Lesenswert?

Ich tippe mal auf Aligment Fehler. Aber schau doch einfach ins Hardfault 
Status Register.

von kernighan ritchie (Gast)


Lesenswert?

>Nu meine ganz einfache Frage:
>Was mache ich falsch?

Ganz einfache Antwort.
Du kannst keine Datentypen und keine Zeiger korrekt verwenden.
Nimm dir noch mal ein C-Buch zur Hand und frische dein Wissen auf.

Was soll das bewirken ?
 *(uint32_t*)&DataArray[2]

Daten in ein Array geht so:
arr[123] = datum;
arr und datum müssen vom selben Datentyp sein, z.B. uint32_t, sonst 
gehts schief. Mit Pointergecaste kann man nicht eine Typwandlung machen. 
Der Hardfault kommt warscheinlich daher, das du auf eine Speicheradresse 
schreibst, die kein RAM ist, da das Schreibziel 
*(uint32_t*)&DataArray[2] irgendeinen zufälligen Wert enthält.

von Jim M. (turboj)


Lesenswert?

Karl schrieb:
> *afaik gibt es einen Modus des kerns der das toleriert. Wird aber selten
> verwendet.

Nicht bei ARMv6-M aka Cortex-M0(+). Der kann das nicht. bei Cortex-M3 
und -M4 geht das per default - allerdings nicht bei 64-bittigen 
Zugriffen (LDRD/STRD).

Hier müsstest Du memcpy() bemühen, das kann normalerweise auch mit 
nicht-aligned Pointern umgehen.

von Thomas (Gast)


Lesenswert?

Michael P. schrieb:
> Hallo zusammen,
>
> ich versuche in meinem Programm Daten in ein Array zu kopieren. Das löst
> jedoch einen "Hard Fault" aus und die CPU bleibt stehen.
> Ich verwende einen STM32F030
> Was mache ich falsch?

Du nimmst den falschen Controller.
Fehlermöglichkeiten ohne Ende!
Steig um auf etwas bei dem Mensch noch den Überblick wahren kann, z.B. 
AVR

von Michael P. (protactinium)


Lesenswert?

Danke für den Hinweis mit dem Alignment. Daran habe ich nicht gedacht. 
Werde die Funktion ein wenig abändern.

@kernighan ritchie
Ich frage mich wer von uns beiden das C-Buch lesen sollte?

@Thomas
Nicht immer kann man sich aussuchen welchen Controller man nimmt, z.B. 
wenn die Werkstatt gerade nix anderes hergibt. Außerdem kann man auch 
bei einem AVR genug Fehler machen.

von kernighan ritchie (Gast)


Lesenswert?

>>Was soll das bewirken ?
>> *(uint32_t*)&DataArray[2]

>Ich frage mich wer von uns beiden das C-Buch lesen sollte?

Mach mich wissend, was macht dieser Code deiner Meinung nach ?

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Michael P. schrieb:
> Danke für den Hinweis mit dem Alignment. Daran habe ich nicht gedacht.
> Werde die Funktion ein wenig abändern.

Du könntest auch ein Struct mit
1
__attribute__ ((packed))
 verwenden. Dann kommt kein Padding dazu.

Dann würde der Compiler (auf umständliche Art und Weise) dafür sorgen, 
dass das Aligning nicht verletzt wird.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

kernighan ritchie schrieb:
> Mach mich wissend, was macht dieser Code deiner Meinung nach ?

Das ist ein normaler Weg, um bei unalligntem Prozessor (z.b. PC) Daten 
in einen Bytebuffer zu bringen (oder heraus zu holen). Wenn man nicht 
(was richtig wäre) memcpy nutzen will.

Die Adresse des dritten Bytes wird gecastet.
Auf einen pointer auf einen 32bit wert.
Und davon der Inhalt.
Steht es links bei der Zuweisung, werden​ DataArray[2...5] beschrieben, 
sonst gelesen.

von 32zuterrtzkutehte (Gast)


Lesenswert?

ich wollte schon fragen warum man den 32it nicht einfach zerlegt
oder memcpy nutzt
1
uint8_t DataArray[11];
2
3
DataArray[2] = (data>>24)&0xFF;
4
DataArray[3] = (data>>16)&0xFF;
5
DataArray[4] = (data>>8)&0xFF;
6
DataArray[5] = (data)&0xFF;
7
8
oder 
9
10
memcpy( &DataArray[2], (uint8_t*)&data ), sizeof(uint32_t));

vieleicht hilft es auch das bytearray passend zu alignen
__attribute(aligned(4))  oder so ...

Thomas schrieb:
> Du nimmst den falschen Controller.
> Fehlermöglichkeiten ohne Ende!
> Steig um auf etwas bei dem Mensch noch den Überblick wahren kann, z.B.
> AVR

aha .. und morgen fangen alle wieder mit trabbi an fahren zu lernen?


ich hatte beim M7 diverse geschwindigkeitsproleme soald das projekt 
größer wird.
compilat ist ca 560kb groß ...
per linker file muss ich nun im linker alles auf 8 alignen

von kernighan ritchie (Gast)


Lesenswert?

>> Mach mich wissend, was macht dieser Code deiner Meinung nach ?
>Das ist ein normaler Weg, um bei unalligntem Prozessor (z.b. PC) Daten
>in einen Bytebuffer zu bringen (oder heraus zu holen).

Da das ja korrekt ist muss der Hardfault ja aus
 /* weitere Verarbeitung */
kommen, sonst ist ja im Codeausschnitt nicht zu sehen.

Beitrag #5137760 wurde von einem Moderator gelöscht.
Beitrag #5137875 wurde von einem Moderator gelöscht.
von kernighan ritchie (Gast)


Lesenswert?

immer diese Empfehlung, einen 8bitter zu nutzen.
Der TO will ein 32bit Datum in ein 8-bit Array kopieren,
da hilft ein Prozesorwechsel auch nichts. Reines Datenschieben
geht dann auch nicht besser ohne C-Kenntnisse.

DataArray[2]  // ein Wert in einem Array, byte aligned
&             // davon die Speicheradresse
(uint32_t*)   // diese Adresse wieder in einen Zeiger gecasted
*             // und davon wieder den Wert

Damit sind die Daten kein einzges mal im RAM neu aligned worden,
sondern nur ihre Deutung umdefiniert.
Wenn schon STM32 und Datenschieben, dann wenigstens mit dem DMA 
Controller.
HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t 
DstAddress, uint32_t DataLength);

DMA konfigurieren, wenn nicht schon geschehen.
Man kann übrigens DMA Kanäle in 8, 16 und 32 bit konfigurieren, je nach 
Bedarf.
{
  hdma_memtomem_dma2_stream4.Instance = DMA2_Stream4;
  hdma_memtomem_dma2_stream4.Init.Channel = DMA_CHANNEL_0;
  hdma_memtomem_dma2_stream4.Init.Direction = DMA_MEMORY_TO_MEMORY;
  hdma_memtomem_dma2_stream4.Init.PeriphInc = DMA_PINC_ENABLE;
  hdma_memtomem_dma2_stream4.Init.MemInc = DMA_MINC_ENABLE;
  hdma_memtomem_dma2_stream4.Init.PeriphDataAlignment = 
DMA_PDATAALIGN_BYTE;
!***!
  hdma_memtomem_dma2_stream4.Init.MemDataAlignment = 
DMA_MDATAALIGN_BYTE;
!***!
  hdma_memtomem_dma2_stream4.Init.Mode = DMA_NORMAL;
  hdma_memtomem_dma2_stream4.Init.Priority = DMA_PRIORITY_LOW;
  hdma_memtomem_dma2_stream4.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  hdma_memtomem_dma2_stream4.Init.FIFOThreshold = 
DMA_FIFO_THRESHOLD_FULL;
  hdma_memtomem_dma2_stream4.Init.MemBurst = DMA_MBURST_SINGLE;
  hdma_memtomem_dma2_stream4.Init.PeriphBurst = DMA_PBURST_SINGLE;
  if (HAL_DMA_Init(&hdma_memtomem_dma2_stream4) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }
}

void MeineFunktion(uint32_t Data)
{
uint8_t *ptr_data = (uint8_t *)&Data;   // Pointer Quelle
uint8_t DataArray[11];
uint8_t *ptr_DataArray = (uint8_t *)&DataArray[2]; // Pointer Ziel

HAL_DMA_Start(&hdma_memtomem_dma2_stream4, ptr_data, ptr_DataArray, 4);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream4, 
HAL_DMA_FULL_TRANSFER,1);

DataArray[6] = (uint8_t)0x09;
    /* weitere Verarbeitung */
}

Für 4 Byte ein bisschen Kanonen auf Spatzen mit DMA, aber dafür gehts. 
Und den DMA Controller sollte man beim Cortex-M immer nutzen, der kann 
Datenschieben besser als die CPU.

Beitrag #5137963 wurde von einem Moderator gelöscht.
von kernighan ritchie (Gast)


Lesenswert?

>> Der TO will ein 32bit Datum in ein 8-bit Array kopieren
>Dann hat er Unmögliches vor.
nicht wenn er es so macht wie gerade gezeigt.

von kernighan ritchie (Gast)


Angehängte Dateien:

Lesenswert?

wer es mal ausprobieren will, geht ganz einfach mit DMA, nur die Maus 
schubsen.

Wer trotzdem den 8bitter nutzen muss, nur als Erinnerung, 32 Bit CPUs 
gibt es seit den 80ern, ebenso DMA mit eben den selben CPUs.
https://en.wikipedia.org/wiki/Amiga_Chip_RAM
Zitat "Under the Amiga architecture, the direct memory access (DMA) 
controller is integrated into the Agnus (Alice on AGA models) chip."

von Konrad (Gast)


Lesenswert?

kernighan ritchie schrieb:
> Wer trotzdem den 8bitter nutzen muss, nur als Erinnerung, 32 Bit CPUs
> gibt es seit den 80ern

Wer trotzdem die einfachere Lösung nutzen muss, nur als Erinnerung, 
weitaus kompliziertere gibt es seit den 80ern :)

von kernighan ritchie (Gast)


Lesenswert?

die Plattform wechseln weil mal was nicht geht würde ich aufgeben 
nennen.
Und wenn es mit 8bit nicht sofort kappt, einen Abacus ?

von Mampf F. (mampf) Benutzerseite


Lesenswert?

kernighan ritchie schrieb:
> Für 4 Byte ein bisschen Kanonen auf Spatzen mit DMA, aber dafür gehts.
> Und den DMA Controller sollte man beim Cortex-M immer nutzen, der kann
> Datenschieben besser als die CPU.

WTF ?

Ja, DMA ist für dieses triviale Problem wirklich mehr als angemessen ...

von 32zuterrtzkutehte (Gast)


Lesenswert?

kernighan ritchie schrieb:
> Für 4 Byte ein bisschen Kanonen auf Spatzen mit DMA, aber dafür gehts.
> Und den DMA Controller sollte man beim Cortex-M immer nutzen, der kann
> Datenschieben besser als die CPU.

Mampf F. schrieb:
> WTF ?
>
> Ja, DMA ist für dieses triviale Problem wirklich mehr als angemessen ...


öhm so blöd das klingt

wenn man mehr als 128 Bytes verschiebt und es keine 32bit sind
ist das per DMA wirklich sogar schneller ^^

wenn 32 bit umkopiert werden sollen geht auch memcpy ganz easy ...
aer ei 8/16bit umkopiererei kommt permanent das alignment dazwischen
ich weiß nicht wie oft ich schon deswegen geflucht habe


ich hab im M7  diverse memcpy funktionen per DMA die aber selbst im ITCM 
ram liegen... also auch schnell durch sind

von Nop (Gast)


Lesenswert?

32zuterrtzkutehte schrieb:

> aer ei 8/16bit umkopiererei kommt permanent das alignment dazwischen
> ich weiß nicht wie oft ich schon deswegen geflucht habe

Eigentlich tritt das Problem überhaupt nur auf, wenn man Daten-IO macht. 
In den anderen Fällen sollte man sich lieber mal anständige 
Datenstrukturen überlegen, das ist sauberer und schneller.

Für IO braucht man aber sowieso entsprechende Routinen zum Konvertieren 
beim Senden und Empfangen, schon weil man sich um Endianess kümmern muß.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

32zuterrtzkutehte schrieb:
> wenn man mehr als 128 Bytes verschiebt und es keine 32bit sind
> ist das per DMA wirklich sogar schneller ^^

Ja und in der Zwischenzeit wartet man, bis der DMA fertig ist? ;-)

von 8x4=32 (Gast)


Lesenswert?

Kaum zu glauben, was hier die 'Gutglückhobbyprogrammierermöchtegern' vom 
Stapel lassen.

Dass der gute uC definiert auf den Hardfault verzweigt, anstatt 
'abzuschmieren', erlaubt den SW-Fehler zu finden. Bei einer anderen CPU 
hätten wir wieder den Thread: Mein AVR stürzt nach 2h ab, was kann ich 
tun?

=> Der Hardfault ist ein tolles feature und keine Last!

von kernighan ritchie (Gast)


Lesenswert?

>Ja und in der Zwischenzeit wartet man, bis der DMA fertig ist? ;-)

Der DMA kann auch einen IRQ auslösen, dann muss man nicht warten.

von 8x4=32 (Gast)


Lesenswert?

Ach ja, und was DMA ist, haben die 'homebrews' auch noch nicht kapiert.
Schei... nein. :-<

DMA läuft in HW, da muss nix gefetcht und (wie meist) über Register 
geladen werden.

von Nop (Gast)


Lesenswert?

8x4=32 schrieb:

> Dass der gute uC definiert auf den Hardfault verzweigt, anstatt
> 'abzuschmieren', erlaubt den SW-Fehler zu finden.

Jein. Ein 8-bitter hat keine Alignment-Probleme, und daher ist es dort 
auch kein SW-Fehler, wenn man z.B. aus einem Paketbuffer sich einen 
32bit-Int direkt rauszieht, ohne sich um Alignment zu kümmern.

Es ist andererseits, wie man sieht, auch nicht portabel, sondern eben 
ein Hack, der (je nach Umsetzung) evtl. bereits in den Bereichen von 
undefined behaviour liegt, wegen pointer aliasing, wenn nicht mit packed 
structs gemacht, die aber auch nicht unbedingt portabel sind.

> => Der Hardfault ist ein tolles feature und keine Last!

Daß der Hardfault kommt, wenn das Alignment gerissen wurde, ist 
natürlich gut, insbesondere wenn man sich mal einen vernünftigen Handler 
schreibt, der einem die fault address und Status auswertet. Anhand des 
Mapfiles kann man immerhin sehen, in welcher Funktion der Fehler 
aufgetreten ist, wenngleich die Ursache natürlich immer noch ganz 
woanders liegen kann.

von Heinz (Gast)


Lesenswert?

kernighan ritchie schrieb:
> wer es mal ausprobieren will, geht ganz einfach mit DMA, nur die
> Maus
> schubsen.
>
> Wer trotzdem den 8bitter nutzen muss, nur als Erinnerung, 32 Bit CPUs
> gibt es seit den 80ern, ebenso DMA mit eben den selben CPUs

... um hier mal keine Mißverständnisse aufkommen zu lassen, DMA bietet 
schon die uralte Z80 Architektur oder bei den AVR- 8Bittern ein Xmega. 
Das ist nichts exklusiv 32-bittiges.

8x4=32 schrieb:
> Dass der gute uC definiert auf den Hardfault verzweigt, anstatt
> 'abzuschmieren', erlaubt den SW-Fehler zu finden. Bei einer anderen CPU
> hätten wir wieder den Thread: Mein AVR stürzt nach 2h ab, was kann ich
> tun?

Watchdog aktivieren?
SW-Fehler sind nicht deswegen schwerer zu finden weil sie 8-bittiger 
Natur sind.

von Nop (Gast)


Lesenswert?

Heinz schrieb:

> Watchdog aktivieren?

Der gibt Dir aber keinen Aufschluß, an welcher Stelle das Problem 
aufgetreten ist.

von Heinz (Gast)


Lesenswert?

Viele Fehler können bei AVR & Co gar nicht auftreten weil sie viel 
einfacher gestrickt sind. So sie dann doch mal auftreten lässt sich ein 
aktivierter Watchdog natürlich wunderbar zur Eingrenzung von Fehlern 
nutzen. Bei diversen Typen gibts dann ja auch noch die 
Hardware-Breakpoints...

von Mampf F. (mampf) Benutzerseite


Lesenswert?

kernighan ritchie schrieb:
>>Ja und in der Zwischenzeit wartet man, bis der DMA fertig ist?
> ;-)
>
> Der DMA kann auch einen IRQ auslösen, dann muss man nicht warten.

Ja schon klar ... Aber in der Regel hat man keine asynchrone 
Datenverarbeitung ... Der Software-Overhead etwas auf asynchron 
umzubauen ist viel größer, als einfach stupide per Memcpy Daten zu 
kopieren.

Oder im Fall vom TE, wo es vermutlich Daten für die Kommunikation mit 
extern ist, definiert man sich ein sauberes (gepacktes) Struct und hat 
all die Probleme nicht - der Compiler macht es dann schon richtig und 
weiß auch, wie man auf unaligned-Daten zugreift.

Dann hat man die Structs auch noch gleich als Dokumentation quasi 
kostenlos inklusive ;-)

Wenn man es per Indizes per Hand per Pointer-Casting auf irgendwas 
selbst macht, gibt es halt Probleme.

Die Lösung ist einfach sauberes Programmieren.

Wenn es sein muss, baut man sich noch ein union, in dem das Struct und 
ein uint8_t-Array ist, dann braucht man nicht mal mehr memcpy.

: Bearbeitet durch User
von Wahnsinn (Gast)


Lesenswert?

Das sind mal wieder Diskussionen hier.......... die keinem helfen.

Für solche leichten Sachen benutze ich gerne einen eigenen Union Type.

Bei dem kannst du auf jedes Byte einzeln zu greifen ohne großen Aufwand.


Pfeifen gibt es hier ......... HAMMER!

von Nop (Gast)


Lesenswert?

Mampf F. schrieb:

> Oder im Fall vom TE, wo es vermutlich Daten für die Kommunikation mit
> extern ist, definiert man sich ein sauberes (gepacktes) Struct und hat
> all die Probleme nicht - der Compiler macht es dann schon richtig und
> weiß auch, wie man auf unaligned-Daten zugreift.

Structs über Datenbuffer zu casten ist fast ein so großer Pfusch wie 
Bitfelder über Register zu legen (Stichwort Endianess). Und der Compiler 
kann unaligned access nur dann richtig machen, wenn die Hardware das 
auch unterstützt, was bei den kleinen Cortexen nicht der Fall ist und 
direkt in einen Hardfault rennt.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Nop schrieb:
> Und der Compiler
> kann unaligned access nur dann richtig machen, wenn die Hardware das
> auch unterstützt, was bei den kleinen Cortexen nicht der Fall ist und
> direkt in einen Hardfault rennt.

Meine Erfahrung mit den früheren ARM7TDMI sagt etwas anderes ... Da 
hatte der Compiler unaligned-Zugriffe auf mehrere aligned-Zugriffe 
aufgeteilt und zur Not auch umständlich wieder zu einem 32Bit Datum 
wieder zusammengebaut - aber halt nicht, wenn man Pointer-Arithmetik 
händisch falsch benutzte ... Aber packed Structs war wie gemeint kein 
Problem.

Bei den größeren (ab M3?) ist das aber nicht mehr notwendig und das weiß 
der Compiler sehr genau :)

Ah, ich hab meinen uralt-Thread wieder gefunden, der genau das Problem 
zeigt, aber auch zeigt, dass der Compiler weiß, was er machen muss bei 
unaligned-Daten:

Beitrag "[WinARM] Data-Alignment lässt grüßen"

Für die click-faulen:

.
1
Ich bin gerade dabei einen .BMP Importfilter für meinen SAM7S zu basteln
2
und wollte mir mal ankucken, wie der mit dem misalignment des
3
Bitmap-Headers zurecht kommt (Optimiert auf größe).
4
5
Das Ergebnis hat mich so schockiert, dass ich es euch nocht
6
vorenthalten will. Schaut es euch mal an und lasst es auf euch wirken.
7
8
Hier der C-Code:
9
10
  buf->width = info.width;
11
  buf->height = info.height;
12
  buf->bpl = info.width*2;
13
14
Und das was rauskommt (Optimierung auf größe!)
15
16
  100388:  e3a06001   mov  r6, #1  ; 0x1
17
  10038c:  1a000024   bne  100424 <>
18
  100390:  e59f30a4   ldr  r3, [pc, #164]  ; 10043c <.text+0x43c>
19
  100394:  e583e000   str  lr, [r3]
20
  100398:  e3e0307b   mvn  r3, #123  ; 0x7b
21
  10039c:  e5c53000   strb  r3, [r5]
22
  1003a0:  e5c5c003   strb  ip, [r5, #3]
23
  1003a4:  e5c5c001   strb  ip, [r5, #1]
24
  1003a8:  e5c5c002   strb  ip, [r5, #2]
25
  1003ac:  e5d42009   ldrb  r2, [r4, #9]
26
  1003b0:  e5d43008   ldrb  r3, [r4, #8]
27
  1003b4:  e5d4100a   ldrb  r1, [r4, #10]
28
  1003b8:  e1833402   orr  r3, r3, r2, lsl #8
29
  1003bc:  e5d4200b   ldrb  r2, [r4, #11]
30
  1003c0:  e1833801   orr  r3, r3, r1, lsl #16
31
  1003c4:  e1833c02   orr  r3, r3, r2, lsl #24
32
  1003c8:  e1a00c23   mov  r0, r3, lsr #24
33
  1003cc:  e1a02423   mov  r2, r3, lsr #8
34
  1003d0:  e1a01823   mov  r1, r3, lsr #16
35
  1003d4:  e5c50007   strb  r0, [r5, #7]
36
  1003d8:  e5c52005   strb  r2, [r5, #5]
37
  1003dc:  e5c51006   strb  r1, [r5, #6]
38
  1003e0:  e5c53004   strb  r3, [r5, #4]
39
  1003e4:  e5d42005   ldrb  r2, [r4, #5]
40
  1003e8:  e5d43004   ldrb  r3, [r4, #4]
41
  1003ec:  e5d41006   ldrb  r1, [r4, #6]
42
  1003f0:  e1833402   orr  r3, r3, r2, lsl #8
43
  1003f4:  e5d42007   ldrb  r2, [r4, #7]
44
  1003f8:  e1833801   orr  r3, r3, r1, lsl #16
45
  1003fc:  e1833c02   orr  r3, r3, r2, lsl #24
46
  100400:  e1a03613   mov  r3, r3, lsl r6
47
  100404:  e1a00c23   mov  r0, r3, lsr #24
48
  100408:  e1a02423   mov  r2, r3, lsr #8
49
  10040c:  e1a01823   mov  r1, r3, lsr #16
50
  100410:  e5c52009   strb  r2, [r5, #9]
51
  100414:  e5c53008   strb  r3, [r5, #8]
52
  100418:  e5c5100a   strb  r1, [r5, #10]
53
  10041c:  e5c5000b   strb  r0, [r5, #11]
54
  100420:  ea000000   b  100428 <>
55
56
Sowas ist doch beeindruckend :-)


q.e.d ;-)

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Mampf F. schrieb:

> Ah, ich hab meinen uralt-Thread wieder gefunden, der genau das Problem
> zeigt, aber auch zeigt, dass der Compiler weiß, was er machen muss bei
> unaligned-Daten:

Danke - beeindruckend und erschreckend zugleich. :-)

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.