Hallo Forum, ich habe eine generelle Frage zu Keil und der Benutzung vom ARM oder THUMB mode. Wenn ich mir ein kleines Testprogramm schreibe und im THUMB mode die STDIO.h mit printf verwende funktioniert alles wunderbar. Wenn ich jedoch im ARM mode bin meckert Keil. Nur wenn ich die putchar Funktion als __THUMB oder generell mit #pragnma THUMB kennzeichne läuft es. Warum ist das bei Keil so? Ist die STDIO nur ein 16 BIT Bibliothek? Mit freundlichen Grüßen Michael PS. Verwende eine LPC2294
@Michael: Hier liegt noch vieles im Argen: Ruft doch mein ARM-Code aus einem Timer-Interrupt eine THUMB-Funktion mit Branch Link (BL) auf, obwohl Interwork eingestellt, und steppt munter durch diese, ohne Fehler und mit gesetztem THUMB Flag...., kein Undefined Mode o.ä.. ARM-THUMB Wechsel sind doch laut ARM Papieren nur mit Branch Exchange (BX) erlaubt. Hallo ARM, was ist denn hier los, wo bin ich denn hier??? Ich melde mich mal wieder zu diesem Thema.... Gruß Dietmar
@Dietmar Wahrscheinlich wird mit BL zu einem Stub gebranched, welcher dann den Wechsel in den Thumb Modus vornimmt. Gruss, Dominic
@Dominic: Da soll mal einer noch auf dem Teppich bleiben... :-) Ich muß doch irgendwie glaubhaft meinen eigenen Code nachvollziehen können. Was meinst du mit Stub? Ich hatte das Disassembler Fenster auf, und da war nichts verstecktes mehr. Was mich sonst noch ärgert, sind noch die Push und Pop Befehle in ARM Mode, die es eigentlich nicht gibt. Da muß man immer wieder suchen, suchen, suchen... Die heißen im Quelltext STMFD und LDMFD. An was soll ich denn noch glauben? Warum macht man sowas? Gruß Dietmar
Ich kenne den Keil Compiler nicht, aber der GCC verwendet zum Interworking (also Thumb-Funktionsaufrufe von ARM Code und vice-versa) kurze Stubs: Main-Funktion (in ARM übersetzt) 400002f8: e2811d09 add r1, r1, #576 ; 0x240 400002fc: eb00009f bl 40000580 <__my_thumb_proc_from_arm> my_thumb_proc (Thumb übersetzt) 400004f4 <my_thumb_proc>: 400004f4: b580 push {r7, lr} 400004f6: 466f mov r7, sp 400004f8: b082 sub sp, #8 ... ... Stub (in ARM übersetzt, aber automatisch vom Linker eingefügt) 40000580 <__my_thumb_proc_from_arm>: 40000580: e59fc000 ldr ip, [pc, #0] ; 40000588 <__my_thumb_proc_from_arm+0x8> 40000584: e12fff1c bx ip 40000588: 400004f5 strmid r0, [r0], -r5 Wenn in Thumb übersetzter Code my_thumb_proc aufruft, wird einfach nach 400004f4 gebranched, der ARM Code ruft __my_thumb_proc_from_arm auf. BL kann ganz einfach keinen Wechsel zwischen ARM und Thumb bewirken, also muss es noch etwas anderes in der fertigen Binary geben. Den BLX Befehl, mit dem man Funktionsaufrufe + Instruction-Set Wechsel auf einmal machen kann gibt es erst in ARMv5, d.h. ARM9xxE oder XScale. Mir ist nicht ganz klar, was du bzgl. Push/Pop meinst - der Thumb Modus besitzt Push/Pop, im ARM Modus werden Store-/Load-Multiple Befehle verwendet. Gruss, Dominic
@Dominic: Danke für die detaillierte Erklärung, aber so habe ich das auch verstanden. Irgendwo muß immer ein BX-Befehl auftauchen. Die Zwischenschaltungen heißen bei RealView "ARM THUMB Veneer Code" oder "THUMB ARM Veneer Code", etwa wie von dir gezeigt, und davon gibt es viele, die funktionieren meistens auch, sind im MAP File angegeben. Nur, im beschriebenen Fall, fehlt dieses Teil. Das hängt doch nicht etwa mit der Exception zusammen, da Exceptions laut User Manual (komplett) im ARM Mode ausgeführt werden (müssen)? Das betrifft doch nur Eintritt und Austritt der Exception, sicher darf man doch innerhalb dieser auch den Mode wechseln und eine THUMB-Funktion aufrufen? >Mir ist nicht ganz klar, was du bzgl. Push/Pop meinst - >der Thumb Modus besitzt Push/Pop, im ARM Modus werden >Store-/Load-Multiple Befehle verwendet. Ganz einfach: Der Compiler-Hersteller, ARM, ersetzt im Listing bei ARM Mode z.B. STMFD SP!, {R0-R12}, durch PUSH SP!, {R0-R12}. Der Binärcode für den PUSH Befehl ist aber der selbe wie für STMFD, wie ich erst durch Vergleich von Assembler-Listings mit C-Listings herausfand. Das irritiert und stört die gute Lesbarkeit enorm. Irgendwas scheint am Debugger faul: Der stellt gelegentlich Code im falschen Modus dar, allerdings entstellt, z.B. wie ein alter Disassembler, der Speicherreservierungen als Code darstellt. Ich muß hier mal weiter nachhaken, ob der Debugger nicht einen Bug hat. Außerdem, schafft er es schon nicht, den letzten Branch Exchange aus dem Startup-Code zu main() auszuführen, und hängt ganz einfach fest, obwohl das Programm ohne Debugger einwandfrei funktioniert. Gruß Dietmar
Frage an Dietmar: Wenn Du von Debugger sprichst, meinst Du den das Debuggen mit dem ULINK-JTAG Interface, oder meinst du das Debuggen im Simlator ? Gruß Dirk
Frage an Dietmar (nochmal im richtigen Deutsch) : Wenn Du vom Debugger sprichst, meinst Du dan das Debuggen mit dem ULINK-JTAG Interface, oder meinst du das Debuggen im Simlator ? Gruß Dirk
@Dirk: Debuggen mit ULINK. Bin gerade dabei, meine Software von Keil nach RealView umzustellen. Und das ist ein Mords-Aufwand. Irgendwie hat aber das Disassembler-Window einen Bug, da zeitweise der Code zufällig mal als ARM mit völlig unsinnigen Befehlen und mal als THUMB dargestellt wird. Wie kann ich denn sonst den Code auf Assembler-Ebene durchsteppen? Ich hab da mal ein paar Software-Spezis hinzugeholt, die mir den Defekt des Disassemblers bestätigen. Da muß ich mich erst mal an Keil wenden. So kann ich nicht richtig arbeiten. Gruß Dietmar
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.