Hallo, habe einen SVC Handler für Cortex M3 entsprechend Handbuch gemacht und es funktioniert :-) Was ich aber nicht verstehe: wieso funktioniert das Return am Ende mit BX LR? Schliesslich ist im SVC Handler im LR nicht die Rücksprungadresse. Nun wird am Ende vom SVC Handler ohnehin der Stack automatisch zurück geholt, so dass der PC ohne zutun wieder stimmt. Somit ist das BX LR aber eigentlich nur ein Dummy, oder? Oder wird an dem Code im LR erkannt, dass jetzt der SVC Handler zurück kommt? *** SVC_Handler TST LR, #4 ; kernel mode? ITE EQ MRSEQ R0, MSP ; kernel stack MRSNE R0, PSP ; user stack SVCHandler_main ; stack contains: r0, r1, r2, r3, r12, r14, previous PC, xPSR ; usage of r0, r1, r2, r3 requires no push to stack LDR R0, [R0, #6*4] ; previous PC LDRB R0, [R0, #-2] ; previous 16-bit low-byte is svc number CMPS R0, #0x33 ; call service e.g. 0x33 BEQ service_33 ... default BX LR ; PC=LR (return) *** Danke!
Lothar schrieb: > Somit ist das BX LR aber eigentlich nur ein Dummy, oder? Oder wird an > dem Code im LR erkannt, dass jetzt der SVC Handler zurück kommt? Ein Sprung an bestimmte spezielle Adressen wird vom Cortex-M Core als Return-from-Exception interpretiert und entsprechend gehandhabt. Zusammen mit dem Sichern der volatilen Register hat ARM es mit diesem kleinen Trick geschafft, Exception-Handler als normale C Funktionen ohne spezielle Kennzeichnung implementieren zu können.
A. K. schrieb: > Ein Sprung in einen speziellen Adressraum am oberen Ende wird vom > Cortex-M Core als eine Variante von Return-from-Exception interpretiert Man könnte also das Return statt mit BX LR auch mit MVN PC, #0 machen?
Lothar schrieb: > Man könnte also das Return statt mit BX LR auch mit MVN PC, #0 machen? Nein, das gilt nicht für jeden Befehl. Nur POP/LDM, LDR und BX. Der Wert enthält auch noch ein paar weitere Informationen. Architecture Reference B1.5.8.
A. K. schrieb: > Exception-Handler als normale C Funktionen Und wie funktioniert das ohne Inline Assembler? Dieser Aufruf funktioniert: asm("svc #0x33"); Und dieser nicht: void __svc(0x33) call_svc_33(void); ... call_svc_33(); Und wie kommt man im SVC Handler an die SVC Nummer: void SVC_Handler(void) { unsigned long *stack = ... svc_number = ((char *)stack[6])[-2]; switch(svc_number) { ... } } Auch in diesem Beispiel ist Inline Assembler (und Wrapper): http://falstaff.agner.ch/2013/02/18/cortex-m3-supervisor-call-svc-using-gcc
Der SVC Handler ist eine Exception davon :) Und die Nummer übergibt man am besten per Register. Dann muss man sich auch nicht mit diesem schwachsinnigen Dekodierverfahren rumärgern.
Der Syscall ist die wohl einzige Exception, bei der man um einen Assembler-Wrapper schlecht herum kommt. Weil sie als einzige Exception Parameter hat und es ohne etwas Assembler-Code etwas schwierig ist, an diese risikofrei heran zu kommen.
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.