Forum: Mikrocontroller und Digitale Elektronik ARM STM32 Calling Convention


von Michael W. (Gast)


Lesenswert?

Ich möchte unter GNU GCC eine Assemlerprozedur con C aus aufrufen.

Ich hab nun "herausgefunden", dass beim Aufruf zunächst die 
Rücksprungadresse in das link register r14 geschrieben wird.

Die Parameter werden mit r0...r3 übergeben. Wenn ich nun den 
Funktionsprototypen als
1
void foo(uint8 par1, uint8 par2)
 definiere, so übergebe ich ja nur 2x8 Bit. Kommen diese nun nach r0 und 
r1, oder wird zunächst r0 aufgefüllt?

Und was passiert, wenn ich ein long long int (=64Bit) übergebe?

Wo ist das ordentlich beschrieben? Ich habe bisher nur ein paar 
Beispiele gefunden, wo man sich das zusammenreimen kann...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Ne Beschreibung als pdf kann ich dir nicht geben, aber deine Fragen 
beantworten.

Michael W. schrieb:
> Ich hab nun "herausgefunden", dass beim Aufruf zunächst die
> Rücksprungadresse in das link register r14 geschrieben wird.
Richtig, also zum Zurückspringen ein MOV PC, LR (LR = R14).

Michael W. schrieb:
> Die Parameter werden mit r0...r3 übergeben. Wenn ich nun den
> Funktionsprototypen als
> void foo(uint8 par1, uint8 par2) definiere, so übergebe ich ja nur 2x8
> Bit. Kommen diese nun nach r0 und
> r1, oder wird zunächst r0 aufgefüllt?
par1 kommt nach R0 und par2 nach R1.
Aufgefüllt wird nur wenns ein 8 bit signed ist, aber da werden nur die 
ersten 24bit des Registers Vorzeichenrichtig aufgefüllt.
Es gilt: 1 Register = 1 Variable (solange die reinpasst).

Michael W. schrieb:
> Und was passiert, wenn ich ein long long int (=64Bit) übergebe?
Das landet dann in R0 und R1.

Weiterhin landen auch alle Variablen auf dem Stack und zur 
ERgebnisübergabe wird R0 genutzt.

Die Befehle STMFD/LDMFD zum registerretten kennste?

von Michael W. (Gast)


Lesenswert?

Danke für die Antwort ;)


Martin Wende schrieb:
> Weiterhin landen auch alle Variablen auf dem Stack und zur
> ERgebnisübergabe wird R0 genutzt.

was heißt das? Zusätzlich zu r0...r3 werden die Parameter immer auf den 
Stack gepusht? Wozu diese Doppelgleisigkeit?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Falls es mal ne Funktion gibt die mehr als 4 Variablen hat zB.

von Michael W. (Gast)


Lesenswert?

d.h. wenn ich 6 Parameter mit jeweils 32Bit übergebe, landen die ersten 
vier in r0...r3 und NUR(!) die restlichen beiden am Stack?

von Detlef K. (adenin)


Lesenswert?


von Dr. Sommer (Gast)


Lesenswert?

Du kannst die Funktion auch als C-Funktion definieren und 
inline-Assembly verwenden, dann ists sogar unabhängig von der 
Calling-Convention... Musst nur die richtigen Constraints angeben um die 
Parameter vom Assemblercode aus ansprechen zu können.

von Uwe Bonnes (Gast)


Lesenswert?

Michael W. schrieb:
> Und was passiert, wenn ich ein long long int (=64Bit) übergebe?
Die werden in R0/1 oder R2/3 uebergeben. Falls R0 oder R2 schon voll ist
wird in R2 oder auf dem Stack auf einer 8-Byte boundary uebergeben.

von Fritz (Gast)


Lesenswert?

Michael W. schrieb:
> d.h. wenn ich 6 Parameter mit jeweils 32Bit übergebe, landen die ersten
> vier in r0...r3 und NUR(!) die restlichen beiden am Stack?

Ja genau so.
Für die floats schaut es beim STM32F4.. anders aus, da landen die float 
parameter in den float registern. Genaueres kann man ergugeln. Da gibt 
es eine Beschreibung der C-calling convention (oder so ähnlich).

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.