Forum: Compiler & IDEs Hile beim Verständnis von ARM Befehlen.


von Olli Z. (z80freak)


Lesenswert?

Hallo, wer kann mir helfen diesen Codeblock zu verstehen?
1
ROM:0000167C                             CODE16
2
ROM:0000167C
3
ROM:0000167C             loc_167C                                ; CODE XREF: ROM:00001678↑j
4
ROM:0000167C                                                     ; DATA XREF: ROM:00001674↑o
5
ROM:0000167C 1D 48                       LDR     R0, =0x20000030
6
ROM:0000167E 85 46                       MOV     SP, R0
7
ROM:00001680 1D 48                       LDR     R0, =0x400
8
ROM:00001682 85 44                       ADD     SP, R0
9
ROM:00001684 1D 48                       LDR     R0, =0x1F58
10
ROM:00001686 01 27                       MOVS    R7, #1
11
ROM:00001688 F8 42                       CMN     R0, R7
12
ROM:0000168A 01 D0                       BEQ     loc_1690
13
ROM:0000168C 00 F0 0F F8                 BL      sub_16AE
14
ROM:00001690
15
ROM:00001690             loc_1690                                ; CODE XREF: ROM:0000168A↑j
16
ROM:00001690 1B 4D                       LDR     R5, =0xFFFFFFFF
17
ROM:00001692 FD 42                       CMN     R5, R7
18
ROM:00001694 05 D0                       BEQ     loc_16A2
19
ROM:00001696 01 E0                       B       loc_169C
20
ROM:00001698             ; ---------------------------------------------------------------------------
21
ROM:00001698
22
ROM:00001698             loc_1698                                ; CODE XREF: ROM:000016A0↓j
23
ROM:00001698 00 F0 3E F9                 BL      sub_1918
24
ROM:0000169C
25
ROM:0000169C             loc_169C                                ; CODE XREF: ROM:00001696↑j
26
ROM:0000169C 10 CD                       LDMIA   R5!, {R4}
27
ROM:0000169E 00 2C                       CMP     R4, #0
28
ROM:000016A0 FA D1                       BNE     loc_1698
29
ROM:000016A2
30
ROM:000016A2             loc_16A2                                ; CODE XREF: ROM:00001694↑j
31
ROM:000016A2 FF F7 3F FE                 BL      sub_1324
32
ROM:000016A6 01 20                       MOVS    R0, #1
33
ROM:000016A8 00 F0 D4 F8                 BL      sub_1854
34
ROM:000016AC             ; ---------------------------------------------------------------------------
35
ROM:000016AC
36
ROM:000016AC             loc_16AC                                ; CODE XREF: ROM:loc_16AC↓j
37
ROM:000016AC FE E7                       B       loc_16AC
38
ROM:000016AE
39
ROM:000016AE             ; =============== S U B R O U T I N E =======================================
40
ROM:000016AE
41
ROM:000016AE
42
ROM:000016AE             sub_16AE                                ; CODE XREF: ROM:0000168C↑p
43
ROM:000016AE 03 25                       MOVS    R5, #3
44
ROM:000016B0 1B E0                       B       loc_16EA
45
....
Am Anfang wird der SP auf 0x2000 0030 gesetzt, was eine Adresse im SRAM 
des betreffenden MPU ist (SRAM geht da von 0x2000 0000 aufwärts). Aber 
dann gehts los...
1
ROM:00001680 1D 48                       LDR     R0, =0x400
2
ROM:00001682 85 44                       ADD     SP, R0
3
ROM:00001684 1D 48                       LDR     R0, =0x1F58
4
ROM:00001686 01 27                       MOVS    R7, #1
5
ROM:00001688 F8 42                       CMN     R0, R7
6
ROM:0000168A 01 D0                       BEQ     loc_1690
7
ROM:0000168C 00 F0 0F F8                 BL      sub_16AE
Mit CMN und BEQ wird wohl konditionell verzweigt, ansonsten auf das 
Label sub_16AE gesprungen (hier als ARM code im restlichen Thumb sumpf). 
Nur was wird da verglichen? Für mich sieht das so aus wie "if (0x1F58 == 
0x0001)" was ja Blödsinn wäre. Und warum wird vorher noch ein Offset 
0x400 auf den SP addiert?

von Larry (Gast)


Lesenswert?

Hast du keinen Debügger*?

Selbst ein Simulator könnte dir helfen...





*) O-Ton der Franzosen bei einem deutschen ST-Workshop.

von Yummi (Gast)


Lesenswert?

Olli Z. schrieb:
> Mit CMN und BEQ wird wohl konditionell verzweigt, ansonsten auf das
> Label sub_16AE gesprungen (hier als ARM code im restlichen Thumb sumpf).

Es tauchen im Code keine ARM happen plötzlich im thumb 2 auf …
Evtl. muss du beim disassemblieren noch den bevorzugten Befehlssatz 
auswählen.

Woher kommt das ganze überhaupt? Ist das vorhandener Assembler Code?
Ist das ein disassembly von irgendwelchem Code? Welche Toolchain? 
Einfach um bestimmte Dinge ausschließen zu können.


Dagegen spricht aus meiner Sicht das SUBROUTINE. Wenn noch ein paar 
Infos kommen würde ich es mir mal anschauen. Teilweise unterscheiden 
sich die Assembler mnemonics minimal von der ARM Doku.

von Olli Z. (z80freak)


Lesenswert?

Habs mit dem versucht: 
https://salmanarif.bitbucket.io/visual/downloads.html
Aber der bringt einen Syntax-Error weil seiner Meinung nach "ADD" einen 
Ziel und zwie Operanden benötigt, IDA hier aber nur einen Operanden 
disassembliert hat.

von Olli Z. (z80freak)


Lesenswert?

Das ganze stammt aus einem ROM bootloader, am Reset-Vector wird auf 
0x1638 gesprungen, da gehts also los und er startet zunächst natürlich 
im ARM modus. Das umschalten auf Thumb erfolgt später.
1
ROM:00001638             ; ---------------------------------------------------------------------------
2
ROM:00001638                             CODE32
3
ROM:00001638
4
ROM:00001638             loc_1638                                ; CODE XREF: ROM:00000000↑j
5
ROM:00001638 CC 00 9F E5                 LDR     R0, =0xFFFECE14
6
ROM:0000163C CC 10 9F E5                 LDR     R1, =1
7
ROM:00001640 B0 20 D0 E1                 LDRH    R2, [R0]
8
ROM:00001644 02 10 81 E1                 ORR     R1, R1, R2
9
ROM:00001648 B0 10 C0 E1                 STRH    R1, [R0]
10
ROM:0000164C B0 00 9F E5                 LDR     R0, =0xFFFECE24
11
ROM:00001650 B0 10 9F E5                 LDR     R1, =0x15
12
ROM:00001654 B0 20 D0 E1                 LDRH    R2, [R0]
13
ROM:00001658 02 10 81 E1                 ORR     R1, R1, R2
14
ROM:0000165C B0 10 C0 E1                 STRH    R1, [R0]
15
ROM:00001660 AC 00 9F E5                 LDR     R0, =0xFFFEC808
16
ROM:00001664 AC 10 9F E5                 LDR     R1, =0xF500F5
17
ROM:00001668 B0 10 C0 E1                 STRH    R1, [R0]
18
ROM:0000166C A8 10 9F E5                 LDR     R1, =0xA000A0
19
ROM:00001670 B0 10 C0 E1                 STRH    R1, [R0]
20
ROM:00001674 01 00 8F E2                 ADR     R0, (loc_167C+1)
21
ROM:00001678 10 FF 2F E1                 BX      R0              ; loc_167C
22
ROM:0000167C             ; ---------------------------------------------------------------------------
23
ROM:0000167C                             CODE16
24
ROM:0000167C
25
ROM:0000167C             loc_167C                                ; CODE XREF: ROM:00001678↑j
26
ROM:0000167C                                                     ; DATA XREF: ROM:00001674↑o
27
ROM:0000167C 1D 48                       LDR     R0, =0x20000030
28
ROM:0000167E 85 46                       MOV     SP, R0
29
ROM:00001680 1D 48                       LDR     R0, =0x400
30
ROM:00001682 85 44                       ADD     SP, R0
31
ROM:00001684 1D 48                       LDR     R0, =0x1F58
32
ROM:00001686 01 27                       MOVS    R7, #1
33
ROM:00001688 F8 42                       CMN     R0, R7
34
ROM:0000168A 01 D0                       BEQ     loc_1690
35
ROM:0000168C 00 F0 0F F8                 BL      sub_16AE
36
ROM:00001690
37
ROM:00001690             loc_1690                                ; CODE XREF: ROM:0000168A↑j
38
ROM:00001690 1B 4D                       LDR     R5, =0xFFFFFFFF
39
ROM:00001692 FD 42                       CMN     R5, R7
40
ROM:00001694 05 D0                       BEQ     loc_16A2
41
ROM:00001696 01 E0                       B       loc_169C
42
ROM:00001698             ; ---------------------------------------------------------------------------
43
ROM:00001698
44
ROM:00001698             loc_1698                                ; CODE XREF: ROM:000016A0↓j
45
ROM:00001698 00 F0 3E F9                 BL      sub_1918
46
ROM:0000169C
47
ROM:0000169C             loc_169C                                ; CODE XREF: ROM:00001696↑j
48
ROM:0000169C 10 CD                       LDMIA   R5!, {R4}
49
ROM:0000169E 00 2C                       CMP     R4, #0
50
ROM:000016A0 FA D1                       BNE     loc_1698
51
ROM:000016A2
52
ROM:000016A2             loc_16A2                                ; CODE XREF: ROM:00001694↑j
53
ROM:000016A2 FF F7 3F FE                 BL      sub_1324
54
ROM:000016A6 01 20                       MOVS    R0, #1
55
ROM:000016A8 00 F0 D4 F8                 BL      sub_1854
56
ROM:000016AC             ; ---------------------------------------------------------------------------
57
ROM:000016AC
58
ROM:000016AC             loc_16AC                                ; CODE XREF: ROM:loc_16AC↓j
59
ROM:000016AC FE E7                       B       loc_16AC
60
ROM:000016AE
61
ROM:000016AE             ; =============== S U B R O U T I N E =======================================
62
ROM:000016AE
63
ROM:000016AE
64
ROM:000016AE             sub_16AE                                ; CODE XREF: ROM:0000168C↑p
65
ROM:000016AE 03 25                       MOVS    R5, #3
66
ROM:000016B0 1B E0                       B       loc_16EA
67
ROM:000016B2             ; ---------------------------------------------------------------------------
68
ROM:000016B2
69
ROM:000016B2             loc_16B2                                ; CODE XREF: sub_16AE+40↓j
70
ROM:000016B2 41 68                       LDR     R1, [R0,#4]
71
ROM:000016B4 08 30                       ADDS    R0, #8
72
ROM:000016B6 0A 1C                       MOVS    R2, R1
73
ROM:000016B8 2A 40                       ANDS    R2, R5
74
ROM:000016BA 0B D1                       BNE     loc_16D4
75
ROM:000016BC 1A 1C                       MOVS    R2, R3
76
ROM:000016BE 2A 40                       ANDS    R2, R5
77
ROM:000016C0 AB 43                       BICS    R3, R5
78
ROM:000016C2 05 D0                       BEQ     loc_16D0
79
ROM:000016C4
80
ROM:000016C4             loc_16C4                                ; CODE XREF: sub_16AE+20↓j
81
ROM:000016C4 04 68                       LDR     R4, [R0]
82
ROM:000016C6 04 30                       ADDS    R0, #4
83
ROM:000016C8 0C 60                       STR     R4, [R1]
84
ROM:000016CA 04 31                       ADDS    R1, #4
85
ROM:000016CC 04 3B                       SUBS    R3, #4
86
ROM:000016CE F9 D1                       BNE     loc_16C4
87
ROM:000016D0
88
ROM:000016D0             loc_16D0                                ; CODE XREF: sub_16AE+14↑j
89
ROM:000016D0 13 1C                       MOVS    R3, R2
90
ROM:000016D2 05 D0                       BEQ     loc_16E0
91
ROM:000016D4
92
ROM:000016D4             loc_16D4                                ; CODE XREF: sub_16AE+C↑j
93
ROM:000016D4                                                     ; sub_16AE+30↓j
94
ROM:000016D4 04 78                       LDRB    R4, [R0]
95
ROM:000016D6 01 30                       ADDS    R0, #1
96
ROM:000016D8 0C 70                       STRB    R4, [R1]
97
ROM:000016DA 01 31                       ADDS    R1, #1
98
ROM:000016DC 01 3B                       SUBS    R3, #1
99
ROM:000016DE F9 D1                       BNE     loc_16D4
100
ROM:000016E0
101
ROM:000016E0             loc_16E0                                ; CODE XREF: sub_16AE+24↑j
102
ROM:000016E0 02 1C                       MOVS    R2, R0
103
ROM:000016E2 2A 40                       ANDS    R2, R5
104
ROM:000016E4 01 D0                       BEQ     loc_16EA
105
ROM:000016E6 A8 43                       BICS    R0, R5
106
ROM:000016E8 04 30                       ADDS    R0, #4
107
ROM:000016EA
108
ROM:000016EA             loc_16EA                                ; CODE XREF: sub_16AE+2↑j
109
ROM:000016EA                                                     ; sub_16AE+36↑j
110
ROM:000016EA 03 68                       LDR     R3, [R0]
111
ROM:000016EC 00 2B                       CMP     R3, #0
112
ROM:000016EE E0 D1                       BNE     loc_16B2
113
ROM:000016F0 F7 46                       MOV     PC, LR
114
ROM:000016F0             ; End of function sub_16AE
115
ROM:000016F0
116
ROM:000016F0             ; ---------------------------------------------------------------------------
117
ROM:000016F2 00                          DCB    0
118
ROM:000016F3 00                          DCB    0
119
ROM:000016F4 30 00 00 20 dword_16F4      DCD 0x20000030          ; DATA XREF: ROM:loc_167C↑r
120
ROM:000016F8 00 04 00 00 dword_16F8      DCD 0x400               ; DATA XREF: ROM:00001680↑r
121
ROM:000016FC 58 1F 00 00 dword_16FC      DCD 0x1F58              ; DATA XREF: ROM:00001684↑r
122
ROM:00001700 FF FF FF FF dword_1700      DCD 0xFFFFFFFF          ; DATA XREF: ROM:loc_1690↑r
123
ROM:00001704 24 CE FE FF off_1704        DCD 0xFFFECE24          ; DATA XREF: ROM:0000164C↑r
124
ROM:00001708 15 00 00 00 dword_1708      DCD 0x15                ; DATA XREF: ROM:00001650↑r
125
ROM:0000170C 14 CE FE FF off_170C        DCD 0xFFFECE14          ; DATA XREF: ROM:loc_1638↑r
126
ROM:00001710 01 00 00 00 dword_1710      DCD 1                   ; DATA XREF: ROM:0000163C↑r
127
ROM:00001714 08 C8 FE FF off_1714        DCD 0xFFFEC808          ; DATA XREF: ROM:00001660↑r
128
ROM:00001718 F5 00 F5 00 dword_1718      DCD 0xF500F5            ; DATA XREF: ROM:00001664↑r
129
ROM:0000171C A0 00 A0 00 dword_171C      DCD 0xA000A0            ; DATA XREF: ROM:0000166C↑r
130
ROM:00001720

von Yummi (Gast)


Lesenswert?

Nur als kleiner Tipp:
LDR RX, =0xXYZVWQUL -> ist RX=*($pc+0xXYZVWQUL)

von Yummi (Gast)


Lesenswert?

Noch offene Fragen?

von Olli Z. (z80freak)


Lesenswert?

Yummi schrieb:
> Nur als kleiner Tipp:
> LDR RX, =0xXYZVWQUL -> ist RX=*($pc+0xXYZVWQUL)

Jab, danke das wusste ich bereits. Hat mich am anfang auch etwas 
gepuzzelt, aber eigentlich ist es logisch by 4 byte langen Instruktionen 
:-) Wobei die Adresse von Label "0xXYZVWQUL" in "Rufnähe" sein muss, 
sprich sich innerhalb eines 12 Bit Offsets befinden muss.

von Olli Z. (z80freak)


Lesenswert?

Yummi schrieb:
> Noch offene Fragen?

Jede Menge! Wie ist das mit der SP rumrechnerei da oben und was hat es 
mit dem "ADD SP, R0" auf sich?

von Yummi (Gast)


Lesenswert?

Olli Z. schrieb:
> Jede Menge! Wie ist das mit der SP rumrechnerei da oben und was hat es
> mit dem "ADD SP, R0" auf sich?

So auf anhieb auch keine Ahnung ... die Operation erscheint auf anhieb 
nicht logisch. Wenn es in die andere Richtung gehen würde mit der Info 
Bootloader -> Speicher für Update Frame.
Ohne Info Bootloader hätte ich Stack Monitoring in den Raum geworfen. 
Aber wie gesagt alles bei invertierter Richtung.

von (prx) A. K. (prx)


Lesenswert?

Olli Z. schrieb:
> Jede Menge! Wie ist das mit der SP rumrechnerei da oben und was hat es
> mit dem "ADD SP, R0" auf sich?

Das LDR/MOV Paar läd den Anfang des Stack-Bereichs, das darauf folgende 
LDR/ADD Paar addiert dessen Grösse, da der SP ja am oberen Ende anfängt.

von Olli Z. (z80freak)


Lesenswert?

A. K. schrieb:
> Olli Z. schrieb:
>> Jede Menge! Wie ist das mit der SP rumrechnerei da oben und was hat es
>> mit dem "ADD SP, R0" auf sich?
>
> Das LDR/MOV Paar läd den Anfang des Stack-Bereichs, das darauf folgende
> LDR/ADD Paar addiert dessen Grösse, da der SP ja am oberen Ende anfängt.

Ah, ok, das heißt das der Stack von 0x2000 0030 bis 0x2000 0430 reicht 
und der SP auf 0x2000 0430 gesetzt wird?

Ich grüble nur über das "ADD SP, R0", was es ja so eigentlich nicht 
geben dürfte. Kann das ein Assembler-Shortcut für "ADD SP, SP, R0" sein?

von Olli Z. (z80freak)


Lesenswert?

Und was kann nun der darauffolgende Code bedeuten?
1
ROM:00001684 1D 48                       LDR     R0, =0x1F58
2
ROM:00001686 01 27                       MOVS    R7, #1
3
ROM:00001688 F8 42                       CMN     R0, R7
4
ROM:0000168A 01 D0                       BEQ     loc_1690
5
ROM:0000168C 00 F0 0F F8                 BL      sub_16AE

Erst wird R0 mit 0x0000 1F58 geladen.
Dann R7 mit 0x0000 0001.
Und nun wird mit CMN verglichen (das Thumb Instruction, nur mit dem 
Lower-Halfword, 16 Bit) ob R0 == R7 ist, also 0x1F58 == 0x0001.
Was soll da denn jemals anderes rauskommen als "ungleich" (NZ, NE)???

Oder könnte es sein das an der von LDR referenzierten Speicherstelle 
(Variable/Konstante) auch halt mal ein anderer Wert stehen könnte als 
0x1F58?

Vielleicht verstehe ich CMN auch noch nicht richtig...

CMP subtrahiert Operand2 von Rn, also 0x1F58 - 0x0001 und setzt die 
Flags (ähnlich SUBS).

CMN addiert (ADDS) Operand2 auf Rn und setzt die Flags. Hmm, da kommt 
dann ja 0x1F59 raus und das würde ggf. nur das S Flag beeinflussen. Habs 
mal testweise durch einen Simulator gejagt und da werden keine Flags 
beeinflußt.

von Larry (Gast)


Lesenswert?

> durch einen Simulator gejagt

Na siehst.

von Nop (Gast)


Lesenswert?

Yummi schrieb:
> Nur als kleiner Tipp:
> LDR RX, =0xXYZVWQUL -> ist RX=*($pc+0xXYZVWQUL)

Nein, ist es nicht. Es wird RX=0xXYZVWQUL ausgeführt, allerdings nicht 
zwingend als direktes Laden, sondern der Assembler soll die Konstante 
0xXYZVWQUL irgendwo in der nähe des PC ablegen und dann automatisch 
einen PC-relativen Load durchführen. Oder es durch MOV ersetzen, wenn 
sich die Konstante als geshifteter 8-bit-Wert darstellen läßt.

Ansonsten würde auch ein Befehl wie "LDR R0, =0x20000030" aus dem 
Assembler-Listing kaum funktionieren.

von Olli Z. (z80freak)


Lesenswert?

Nop schrieb:
> Yummi schrieb:
>> Nur als kleiner Tipp:
>> LDR RX, =0xXYZVWQUL -> ist RX=*($pc+0xXYZVWQUL)
> Nein, ist es nicht. Es wird RX=0xXYZVWQUL ausgeführt

Genau! Auf den Trichter bin ich zwischenzeitlich auch gekommen :-)
Diese Schreibweise ist halt der ARM Syntax geschuldet, das jeder Befehl 
32 Bit (4 Byte) lang ist.

von (prx) A. K. (prx)


Lesenswert?

Olli Z. schrieb:
> Diese Schreibweise ist halt der ARM Syntax geschuldet, das jeder Befehl
> 32 Bit (4 Byte) lang ist.

Wie man bereits in deinem Eröffnungsbeitrag erkennen kann, ist das 
keineswegs der Fall. Die meisten Befehle darin sind 16 Bits breit.

Die Syntax der Assembler-Notation hat allenfalls indirekt mit der 
Bitbreite der Befehle zu tun. Die =xxxx Syntax hat damit zu tun, dass 
man keine beliebigen 32-Bit Werte in einem Befehl laden kann, und dies 
deshalb ersatzweise gerne PC-relativ tut.

: Bearbeitet durch User
von Olli Z. (z80freak)


Lesenswert?

A. K. schrieb:
> Olli Z. schrieb:
>> Diese Schreibweise ist halt der ARM Syntax geschuldet, das jeder Befehl
>> 32 Bit (4 Byte) lang ist.
>
> Wie man bereits in deinem Eröffnungsbeitrag erkennen kann, ist das
> keineswegs der Fall. Die meisten Befehle darin sind 16 Bits breit.
Naja, ich wollte jetzt nicht spitzfindig sein weil es nichts zur Sache 
tut, wir schreiben ja keine wissenschaftliche Dissertation... aber 
Maschinenkommandos aus dem ARM Befehlssatz sind immer 32 Bit, die 16 Bit 
langen sind THUMB, was ein ganz anderer Befehlssatz ist.

> Die Syntax der Assembler-Notation hat allenfalls indirekt mit der
> Bitbreite der Befehle zu tun.
Volle Zustimmung.

> Die =xxxx Syntax hat damit zu tun, dass
> man keine beliebigen 32-Bit Werte in einem Befehl laden kann, und dies deshalb 
ersatzweise gerne PC-relativ tut.
Was aber wiederrum nicht an Assembler liegt sondern an der Tatsache das 
man nur so 32 Bit Werte in ein Register laden kann. Assembler bedient 
sich hier nur dieser Schreibweise um das lesen zu erleichtern.

von S. R. (svenska)


Lesenswert?

Olli Z. schrieb:
> aber Maschinenkommandos aus dem ARM Befehlssatz
> sind immer 32 Bit, die 16 Bit langen sind THUMB,
> was ein ganz anderer Befehlssatz ist.

Und ein Cortex-M3 oder Cortex-M4 versteht beide nicht, insofern ist die 
Trennung irrelevant. Das einzige Relikt aus der Trennung für diese Cores 
ist, dass PC immer ungerade geschrieben werden muss, sonst bumm.

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.