Call int

Hallo,

habe eine MPU (STM8S105xyz) und will mein C-Programm an eine Adresse springen lassen, quasi den PC auf diese Adr setzen, einen CALL veranstalten. Die (Ziel)Adresse liegt in einer int vor, der Adressraum passt da rein.

  • Goto will ein Label.
  • Ein _asm (call adr) braucht diese absolut-adr und nicht meine int-var.

Muss ich meine int an eine definierte Stelle legen, und diese mit
_asm (call (adr)) anspringen ?

Gibt es eine andere (einfachere) Möglichkeit, in C die Kontrolle ab zu geben ? Adr ist zur Compiler Laufzeit noch nicht bekannt.

Fragt sich und Euch freundlichst

Uwe P.

P.S. Die Adr zur Kontrollübergabe soll variabel gehalten werden.

Hallo nochmals,

Muss natürlich lauten :

_asm (call [adr]) ;

in meinem konkreten Fall
_asm(„CALL [$8002.w]“) ;
[adr] ist dabei fix, aber der Inhalt unter adr ist flexibel.

Gibt es eine andere (einfachere) Möglichkeit, in C die
Kontrolle ab zu geben ?

So sind sie, die Programmierer, eine Zeile Assembler ist schon zu viel. Wichtig ist erst einmal: So geht es. Die Frage sollte eher lauten:

Gibts was in C selbst dafür, oder muss ich _asm() nutzen ?

freundlichst

Uwe P.

Servus,

ein ASM CALL ist zweifellos die sicherere Variante. Man kann aber auch in C an eine bestimmte Adresse springen:

int addr = 0x42424242;
((void(\*)()) addr) ();

Die Idee ist, dass man die Variable in einen Funktionszeiger vom Typ void(*)() castet und aufruft. Es besteht aber die Gefahr, dass der Compiler dabei noch unerwünschte Sachen tut (Stackframe anlegen, o.ä.).

Gruß
Chondron

1 Like

Servus,

ein ASM CALL ist zweifellos die sicherere Variante. Man kann
aber auch in C an eine bestimmte Adresse springen:

int addr = 0x42424242;
((void(*)()) addr) ();

Die Idee ist, dass man die Variable in einen Funktionszeiger
vom Typ void(*)() castet und aufruft. Es besteht aber die
Gefahr, dass der Compiler dabei noch unerwünschte Sachen tut
(Stackframe anlegen, o.ä.).

Ich freue mich über Deine Antwort !

Es ist schon erstaunlich, dass eine „hardwarenahe“ Sprache 10 Klammerzeichen benötigt, um einen call zu generieren, und dann noch mit Seiteneffekten. Das wichtige für mich ist: Es geht in C. Werde es ausprobieren und sehen, was mein Compiler daraus macht.
Vielen Dank für Deine Antwort.

Angenehmes Restwochenende,

Uwe P.

Hallo,

naja, C ist zwar relativ hardwarenah, aber grade das Management der Funktionsaufrufe, also das Auf- und Abbauen der Stackframes, ist eine der (willkommenen) Abstraktionen. Wenn man da manuell eingreifen möchte, bleibt einem für eine saubere, wohldefinierte Lösung nichts anderes übrig als Assemblercode zu schreiben.
Aber es würde mich schon mal interessieren, was Dein Compiler draus macht. Unter x86 funktioniert der Trick vermutlich nicht, weil der Compiler bei einem Funktionsaufruf den Basepointer des Stacks pusht und überschreibt, was zum Absturz führt wenn der Stackframe nicht nachher wieder ordnungsgemäß abgebaut wird.

Gruß
Chondron

Hallo,

Aber es würde mich schon mal interessieren, was Dein Compiler
draus macht.

Sorry, hatte eine ziemlich ausführliche Antwort zusammen, und habe final die Enter-Taste nicht sauber getroffen. In Konsequenz ist der ganze Text flöten. Aktuell habe ich nicht den Nerv auf eine 2. loop.

Also 1. Punkt : Bekomme den Prototype nicht hin.

#error cpstm8 q5main.c:49(23) missing )

Bin für Hilfe (Funktions-proto) dankbar.

Dann 2. Punkt : Bei Übergabe von 2 Chars wird kein Stack benutzt. Sieht für mich jedenfalls so aus, dann sollte eine (16 Bit-int) ebenfalls über (16 Bit) Register X übergeben werden.

q5main.c:152 LED_R(0x00, 0x00) ;
0x87e2 0x5F CLRW X CLRW X
0x87e3 0xCD8679 CALL 0x8679 CALL LED_R

Sollte also durchaus gehen, ohne C zu verlassen.

Gruss,

Uwe P.

Hallo,

#error cpstm8 q5main.c:49(23) missing )

Bin für Hilfe (Funktions-proto) dankbar.

Ohne einen Ausschnitt des entsprechenden Codes wo der Fehler auftritt kann ich da jetzt nicht viel sagen. Mein Beispielcode vom Anfang müsste funktionieren, das hab ich mal getestet. Missing ) sieht aber sehr nach einem schlichten Syntaxfehler aus.

Dann 2. Punkt : Bei Übergabe von 2 Chars wird kein Stack
benutzt. Sieht für mich jedenfalls so aus, dann sollte eine
(16 Bit-int) ebenfalls über (16 Bit) Register X übergeben
werden.

_q5main.c:152 LED_R(0x00, 0x00) ;

0x87e2 0x5F CLRW X
CLRW X

0x87e3 0xCD8679 CALL 0x8679
CALL LED_R_

Sollte also durchaus gehen, ohne C zu verlassen.

Stimmt, seh ich genauso.

MfG
Chondron