Forum: Mikrocontroller und Digitale Elektronik TBB-Befehl im Thumb2 Befehlssatz


von Aspire (Gast)


Lesenswert?

Hallo Leute,
ich beiss mir grad an einem Assemblerbefehl im THUMB2 Set die Zähne aus. 
Und zwar handelt es sich um den TBB bzw TBH Befehl. Mit ihm soll es 
möglich sein eine switch/case Anweisung in Assembler zu realisiern. 
Allerdings kann ich da so garnix mit anfangen. Ein Beispiel lässt sich 
auch nicht finden.
Sehr geholfen wäre mir, wenn jemand die genau Funktion des Befehls mal 
erklären würde. Oder zumindesteine Vorgehensweise.
Unter folgendem Link findet man eine kurze Beschreibung, vllt hilft sie 
ja euch weiter.

http://www.keil.com/support/man/docs/armasm/armasm_cjafifbd.htm

Vielen Dank schon mal im Vorraus.

MfG

von Jörg G. (joergderxte)


Lesenswert?

Die Beschreibung hinter deinem Link Beschreibt den Befehl doch scheinbar 
ganz gut:
- Du brauchst eine Liste mit offsets ("Sprungdistanzen") im Speicher 
(Bytes/Halfwords, daher TBB/TBH)
- in Rn kommt die Adresse der Tabelle (mittels Label)
- in Rm der index, d.h. welcher Sprung genommen werden soll
- für dein switch-case musst du den index eben passend setzen/berechnen
- der ARM springt anschließend entsprechend weiter

Nur: Wie man diese Tabelle in Assembler geschickt erstellt, muss noch 
ausgeknobelt werden ;)

hth, Jörg
ps.: http://de.wikipedia.org/wiki/Sprungtabelle hilft dir evtl. auch 
weiter

von Aspire (Gast)


Lesenswert?

Ja genau daran scheuert es momentan auch bei mir. Wie ich diese Tabelle 
geschickt aufbau.
Aber deine kurze Zusammenfassung hat schon mal Licht ins dunkle 
bebracht, Danke.

von Jörg G. (joergderxte)


Lesenswert?

Nach näherem hinsehen (Ich würde ARMe ganz sicher nicht in Assembler 
programmieren) könntest du sowas probieren (ungetestet! - Ich hab keine 
Ahnung von ARMs, hab mir nur die verlinkte doku angeschaut):
1
jmptable DCB jmpstart - target0 ; Assembler soll das ausrechnen
2
         DCB jmpstart - target1
3
;  ...
4
5
jmpstart TBB ...
6
;  ...
7
target0 ...
8
9
target1 ...
Aber die Doku scheint ja ziemlich ausführlich zu sein.

hth, Jörg - der C bevorzugt ;)

von Random .. (thorstendb) Benutzerseite


Lesenswert?

so weit ich weiss, ist Thumb2 "compileroptimiert" und nicht unbedingt 
dafür gedacht, das per Hand zu coden.
Hast du das ganze mal in C probiert und die das Resultat des armcc 
angesehen, ob es sich überhaupt lohnt, das ganze in ASM zu coden?

VG,
/th.

von Aspire (Gast)


Lesenswert?

Das Problem ist,dass ich an Assembler gebunden bin, da ich nen CUP Test 
schreiben will und dass eben nur auf dieser Ebene effektiv ist. Auf die 
Idee mit dem C-code kam ich auch schon. Hab ne switch/case Anweisung 
geschrieben und dann mit Hilfe des Disassembly und dem Debugger 
analysiert. Allerdings realisiert der Compiler die switch/case recht 
primitiv und der TBB-Befehl kommt nicht zum Einsatz.

In allen anderen Fällen würd ich selber zu C tendieren, da es einfach 
komfortabler ist.

von Jörg G. (joergderxte)


Lesenswert?

> Allerdings realisiert der Compiler die switch/case recht
> primitiv und der TBB-Befehl kommt nicht zum Einsatz.
Da gibt es drei Möglichkeiten, warum der Compiler das so macht:
1) Der Compiler kennt kein TBx (ist theoret. Möglich, der 
Thumb2-Befehlssatz ist ziemlich neu)
2) Der Compiler ist angewiesen keine Sprungtabellen zu nutzen (z.B. 
beim GCC kann man das explizit an/ausschalten, die Optimierung ist ganz 
abgeschaltet, o.ä.).
3) Der Comipler ist schlauer als du ( denkst... ) und hat erkannt, dass 
es anders schneller ist (Der Compiler "weiß" wie teuer die Tabelle inkl. 
Vorbereitung etc. ist und "denkt" z.B. auch an das pipelining und 
ähnliche µC-Spezialitäten) - das passiert ganz besonders bei 
"einfachen" Tests.

hth. Jörg
ps.: Schreib deinen Code in C und arbeite ggf. mit den erzeugten 
Assemblerdateien weiter.

von Aspire (Gast)


Lesenswert?

Genau das ist es ja. Wenn ich das zeug in C schreibe und dann den 
Assemblercode generieren lasse, wird die Switch/Case Anweisung anders 
realisiert. Ich bentutze den Cortex M3 von STM und der kann den THUMB2. 
Mein Problem ist der CPU Test. Es müssen alle Befehle des Befehlssatztes 
einmal auf ihren Funktionalität getestet werden. Und da komm ich um den 
TBx Befehl nicht rum. Auf die Switch/Case bin ich gekommen, da ich 
gelesen hab, das eben dieser Befehl genutzt wird um Switch/Case 
effektiver zu realiesieren.
Hoffe mal das Problem wird jetzt etwas klarer, Sorry anfangs undeutlich 
ausgedrückt.

Aber die Idee mit der Tabelle und so von eben werd ich auf jeden Fall 
mal testen, klingt auf jeden Fall plausibel. Wie genau die Sprungtabelle 
jetzt aufzubauen ist versuche ich noch rauszubekommen. Wenn ich ein Paar 
Erfolge verbucht hab, werd ich den Code auch mal Posten. Bis jetzt hab 
ich aber nur ein paar nichtssagenden Konstrukte.
VG

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Aspire wrote:
> Das Problem ist,dass ich an Assembler gebunden bin, da ich nen CUP
> Test schreiben will und dass eben nur auf dieser Ebene effektiv ist.

Was ist denn ein CUP Test?

> Auf die Idee mit dem C-code kam ich auch schon. Hab ne switch/case
> Anweisung geschrieben und dann mit Hilfe des Disassembly und dem
> Debugger analysiert. Allerdings realisiert der Compiler die
> switch/case recht primitiv und der TBB-Befehl kommt nicht zum
> Einsatz.

Höhere Optimierungsstufe verwenden. Oder nimmst Du einen GCC? Der 
schwächelt manchmal, was Cortex-M3 angeht. Ich empfehle am ehesten den 
von CodeSourcery.

@Jörg
>Ich würde ARMe ganz sicher nicht in Assembler programmieren

"ARMe" schon, nur nicht "Thumbe". Und vor allem keine komplizierten
Kontrollstrukturen.

Das Beispiel von Jörg war fast korrekt, aber Du musst die errechneten
Werte der Tabelle noch durch zwei teilen.

Hier ist ein Beispielprogramm (Vorsicht: Endlosschleife am
Programmende):
1
  AREA fiftyone, CODE, READONLY
2
  THUMB
3
4
  ENTRY
5
main
6
  LDR  r0,  =0
7
  LDR  r1,  =1
8
  LDR  r12, =jumptable
9
10
  CBZ  r1, case0
11
  CMP  r1, #4
12
  BGT  default
13
  SUBS  r1, #1
14
  
15
tablehead
16
  TBB  [r12, r1]
17
18
begintable
19
case1
20
  ADDS  r0, #1
21
  B  endtable
22
case2
23
  ADDS  r0, #2
24
  B  endtable
25
  
26
case3
27
  ADDS  r0, #3
28
  B  endtable
29
  
30
case4
31
  ADDS  r0, #4
32
  B  endtable
33
34
case0
35
default
36
endtable
37
38
stop
39
  B  .
40
41
jumptable
42
  DCB  (case1 - begintable)/2
43
  DCB  (case2 - begintable)/2
44
  DCB  (case3 - begintable)/2
45
  DCB  (case4 - begintable)/2
46
47
  END

Gruß
Marcus
http://www.doulos.com/arm/

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.