93 @ Enable the CCM RAM and all GPIO peripheral clock
6
94 15ea 1949 ldr r1, = RCC_AHB1ENR
7
95 15ec 1948 ldr r0, = BIT20+0x1FF
8
96 15ee 0860 str r0, [r1]
9
97
10
98 @ Set PORTB pins in alternate function mode
11
99 15f0 1949 ldr r1, = GPIOB_MODER
12
100 15f2 0868 ldr r0, [r1]
13
101 15f4 50F42000 orrs r0, #0x00A00000
14
102 15f8 0860 str r0, [r1]
Wieso wird in Zeile 94 nur ein 0x1949 generiert, wo doch
1
.equ RCC_BASE , 0x40023800
2
.equ RCC_AHB1ENR , RCC_BASE + 0x30
also in dem generierten Code doch die Daten 0x40023830 irgendwo
auftauchen müßten? Ähnlich auch in allen Zeilen, wo 32bit immediate
Daten vorkommen?
Liegt das am Thumb-Instruction set?
Grüße
Christoph
Bei einer 32-bit-RISC-Maschine gibt's (normalerweise) keine
32-bit-Direktoperanden.
Üblich bei ARM ist es, die entsprechenden Werte PC-relativ hinter den
Code der Funktion zu legen.
Jörg W. schrieb:> Bei einer 32-bit-RISC-Maschine gibt's (normalerweise) keine> 32-bit-Direktoperanden.>> Üblich bei ARM ist es, die entsprechenden Werte PC-relativ hinter den> Code der Funktion zu legen.
Ah, danke. Verstehe immer mehr. :)
Jörg W. schrieb:> Bei einer 32-bit-RISC-Maschine gibt's (normalerweise) keine> 32-bit-Direktoperanden.>> Üblich bei ARM ist es, die entsprechenden Werte PC-relativ hinter den> Code der Funktion zu legen.
PC-relativ: wo finde ich dann die Konstanten/Direktoperanden im
Assembler listing? Und wie würde z.B. die Instruktion 0x1949
disassemblieren?
Christoph K. schrieb:> PC-relativ: wo finde ich dann die Konstanten/Direktoperanden im> Assembler listing?
Ist mir jetzt auch nicht klar. Ich habe bislang nur compiler-generierten
Assemblercode für Cortex-M gesehen, noch nie selbst welchen geschrieben.
Das sieht dann ungefähr so aus:
1
trx_interface_init:
2
@ args = 0, pretend = 0, frame = 0
3
@ frame_needed = 0, uses_anonymous_args = 0
4
ldr r2, .L9
5
mov r1, #65536
6
mov r0, #32768
7
ldr r3, [r2]
8
orr r3, r3, #16
9
push {r4, r5, r6, lr}
10
str r3, [r2]
11
mov r3, #131072
12
ldr r4, .L9+4
13
mov r2, #16384
14
mov r5, #1024
15
ldr r6, .L9+8
16
str r3, [r4, #48]
17
str r3, [r4, #16]
18
str r3, [r4]
19
ldr r3, .L9+12
20
str r1, [r4, #48]
21
str r1, [r4, #16]
22
str r1, [r4]
23
str r2, [r3, #52]
24
str r2, [r3, #16]
25
str r2, [r3]
26
ldr r2, .L9+16
27
str r0, [r3, #52]
28
str r0, [r3, #16]
29
str r0, [r3]
30
str r5, [r6, #16]
31
str r1, [r2, #20]
32
str r1, [r2, #196]
33
str r1, [r2, #212]
34
str r1, [r2, #176]
35
str r1, [r2, #96]
36
str r1, [r2, #32]
37
str r1, [r2]
38
str r0, [r2, #20]
39
str r0, [r2, #196]
40
str r0, [r2, #212]
41
str r0, [r2, #176]
42
str r0, [r2, #96]
43
str r0, [r2, #32]
44
str r0, [r2]
45
movs r2, #1
46
str r5, [r4, #20]
47
mov r0, #1073741824
48
str r5, [r4]
49
mov r4, #134217728
50
str r2, [r3]
51
movs r5, #4
52
str r2, [r3, #16]
53
str r2, [r3, #52]
54
mov r2, #536870912
55
str r2, [r3, #52]
56
str r2, [r3, #16]
57
str r2, [r3]
58
str r0, [r3, #52]
59
str r0, [r3, #16]
60
str r0, [r3]
61
str r4, [r3, #52]
62
str r4, [r3, #16]
63
str r4, [r3]
64
mov r4, #268435456
65
str r4, [r3, #52]
66
str r4, [r3, #16]
67
str r4, [r3]
68
ldr r4, .L9+20
69
str r5, [r4, #48]
70
str r5, [r4, #16]
71
str r1, [r6, #16]
72
mov r1, #14336
73
str r1, [r3]
74
str r1, [r3, #16]
75
str r1, [r3, #96]
76
mov r1, #6144
77
str r1, [r3, #48]
78
mov r1, #8192
79
str r1, [r3, #48]
80
str r0, [r3, #52]
81
str r2, [r3, #52]
82
pop {r4, r5, r6, pc}
83
.L10:
84
.align 2
85
.L9:
86
.word 1074299156
87
.word 1074663936
88
.word 1074660864
89
.word 1074664448
90
.word 1074662912
91
.word 1074663424
.L9 ist die besagte Tabelle, im Code bezieht sich der Compiler als
.L9+<offset> drauf.
Kann sein, dass der Assembler dafür irgendeine eigene Mimik hat.
.pool: Tell the assembler where it can safely place data for immediate
32bit loads (ideally after your return). Use the = prefix operator to
pool the value. ldr r0, =0x4000002
Es scheint so, als benutzte der Original-Autor
.ltorg für die Konstanten
Das, was in Deinem Beispiel unter .L9 zu finden ist, sind aber
Konstanten aus dem C-Code. Damit wird r0 ja als Basiszeiger
initialisiert.
Das wäre ja dann keine pc-relative Adressierung.
Interessant wäre mal, den Code 0x1949 zu disassemblieren (nur so als
Beispiel zum Beispiel ) :)
Christoph K. schrieb:> Das wäre ja dann keine pc-relative Adressierung.
Die zugehörigen ldr-Befehle sind meiner Meinung nach am Ende pc-relativ.
Das, was sie darin verwenden, natürlich nicht.
Das mit dem .pool klingt logisch, das "=" ist dann so eine Art Abkürzung
dafür, dass man nicht laufend im Assembler-Quelltext hin und her
springen muss zwischen dem Code und der Tabelle.
nehmen.
Aber was ich eigentlich suche, ist ein Assembler-Manual für den
Cortex-M4 und/oder Arm-Thumb, indem die Instruktionen für einen, der
einen Assembler schreiben will, erklärt sind. Das Cortex-Manual PM0214
nennt sich zwar "Programming Manual", aber es fehlen die "Bits". Ich
will einfach mal eine Instruktion selbst "auseinandernehmen" (oder
zusammenbauen).
Christoph K. schrieb:> Aber was ich eigentlich suche, ist ein Assembler-Manual für den> Cortex-M4 und/oder Arm-Thumb, indem die Instruktionen für einen, der> einen Assembler schreiben will, erklärt sind.
Wie, du willst dein Leben radikal ändern?
> Das Cortex-Manual PM0214> nennt sich zwar "Programming Manual", aber es fehlen die "Bits".
Na dann klick dich mal durch:
https://developer.arm.com/architectures/instruction-sets/base-isas/t32
Was du möchtest sind wohl die "Architecture Reference Manuals". Ja,
Mehrzahl. Alleine für Thumb drei Profiles. Jedes Profile mehrere
Versionen, zum Teil mit Suplements. Hier ist z.B. das für ARMv8-M
https://developer.arm.com/documentation/ddi0553/latest 2000+ Seiten. Die
für ARMv6 und ARMv7 sind kleiner.
> will einfach mal eine Instruktion selbst "auseinandernehmen".
Wir sehen uns dann in ein, zwei Jahren :)
Melde mich schon etwas früher zurück. Danke für die Links.
Konnte das jetzt nachvollziehen und meine Neugier ist erst mal gestillt.
Die 0x1949, die ich mal zerlegen wollte, ist ein (im assembler listing):
15ea 1949 ldr r1,=RCC_AHB1ENR. @entspricht 0x40023830
Das Manual DDI0553B_m_armv8m_arm.pdf sagt auf Seite 647:
C2.4.75 LDR (literal)
4 9 1 9
|0100|1rrr|immed|iate 8|
Auswertung:
FORTH
ok
hex ok
19 4 * 15ea + . 164e ok
Schaue ich im gdb das Memory bei 0x164e ab, so steht dort der
Immediate-Wert
0x40023830
Grüße
Christoph