Es ist vielleicht in dem alten Beitrag untergegangen, aber nach dem ich
alle Möglichkeiten die mir eingefallen sind durch habe, probiere ich es
aus Verzweiflung hier noch mal.
{__asm__ (" LedOn = 0x0801001D ...
LedOn ist eine Funktion, die an Adresse 0x0801001D liegt.
Die Adresse liegt auch auch indirekt im Speicher 0x08010000.
Ich möchte diese Adresse der Funktion indirekt aus dem Speicher
zuweisen.
Also in etwa so:
{__asm__ (" LedOn = [0x08010000] ... //dort steht 0x0801001D
Funktioniert so aber nicht.
Gibt es hier einen asm Profi, der mir zeigt, wie es richtig gemacht
wird?
Ist für STM32, sollte aber für alle ARM unter GCC gleich sein.
Danke schon mal.
Hä?
pegel schrieb:> LedOn ist eine Funktion, die an Adresse 0x0801001D liegt.
Ok.
> Die Adresse liegt auch auch indirekt im Speicher 0x08010000.> Ich möchte diese Adresse der Funktion indirekt aus dem Speicher> zuweisen.> Also in etwa so:>> {__asm__ (" LedOn = [0x08010000] ... //dort steht 0x0801001D>> Funktioniert so aber nicht.
Was soll da auch funktionieren? Die Funktion liegt da, wo sie liegt, an
Adresse 0x0801001D. Der kannst und sollst und willst du nichts zuweisen.
Warum auch, die liegt doch schon da, wo du die haben willst.
Was also willst du wirklich erreichen?
Oliver
Und was hat das mit deiner Frage zu tun? Die ist nach wie vor völlig
abstrus und wirr.
Um mal eine zu beantworten: der Compiler kann keine Speicherstellen
auslesen.
Oliver
Warum ist das so wichtig, wo die Funktion liegt?
Darum kümmere ich mich nie, das macht der Linker.
Kann man auch wunderbar mit dem C/C++ Mitteln bekommen.
https://www.c-plusplus.net/forum/topic/301522/adresse-funktion-ausgeben
und mit C kann man diesen Wert auch wunderbar überall in den Speicher
schreiben.
Wozu noch dieses asm-Inline gefrickel?
pegel schrieb:> Doch, passt schon. Es geht um BluePill Funktionen in den oberen 64k, die> fest sind und von vielen Projekten genutzt werden.
Gibt auch keinen Sinn IMHO. Bei ARM ist nichts magisches an der 64K
Grenze. Funktionspointer sind 32 Bit lang. Funktionspointer sind auch zu
int castbar. Und dann in ein Array von int speicherbar. Falls ich das
jetzt richtig verstanden habe und du eine Menge von Funktionen in Form
einer Vektortabelle verfügbar machen willst.
Wie gesagt, ein neues Projekt soll ihm unbekannte Funktionen aus den
oberen 64k kennen lernen und benutzen.
BluePill ist nur der Test. Andere externe Speicher kommen später dazu.
Es geht wirklich nur um die Adresszuweisung um Handarbeit zu sparen.
Es funktioniert ja schon.
pegel schrieb:> Ist für STM32, sollte aber für alle ARM unter GCC gleich sein.
typedef uint32_t LedOn_t (uint32_t arg1); // function prototype
LedOn_t LedOn = (LedOn_T) 0x0801001D;
(prx) A. K. schrieb:> pegel schrieb:>> Ist für STM32, sollte aber für alle ARM unter GCC gleich sein.>> typedef uint32_t LedOn_t (uint32_t arg1); // function prototype> LedOn_t LedOn = (LedOn_T) 0x0801001D;
Clipboard-Fehler. Korrekt:
1
typedefuint32_tLedOn_t(uint32_targ1);// function prototype
Da gibt es einen Trick bein GCC:
Du kannst im Assembler ein globales Label definieren, und dann einen
Function Protype mit dem gleichen Namen definieren.
Beispiel:
1
asm(".globl myCrazyFunc");
2
asm("myCrazyFunc = 0x1234567");
3
4
extern"C"voidmyCrazyFunc(inta,intb);
Definiert eine Funktion mit dem im Prototype angegebenen Parametern, die
der Linker dann auf einen Aufruf an die Adresse 0x1234567 auflöst.
Wenn Du mit C programmierst, dann kannst Du das "extern C" natürlich
weglassen.
Ich denke, das ist genau das, was Du gesucht hast.
Gruß,
Nils
Es gibt schlicht keinen asm-„Befehl“, der das tut, was du möchtest. Du
kannst einem Label (was anderes ist ein Funktionsname nicht) nur direkt
einen Wert zuweisen, so, wie es in den Beispielen zuvor gemacht wurde.
Eine indirekte Zuweisung „hole den Wert dazu aus einer Speicherstelle“
gibt es auf dieser Sprachebene nicht.
Es gibt im Befehlssatz des Prozessors Befehle für indirekte Sprünge.
Guggst du Befehlsreferenz…
Die musst du dann passend mit anderen in der richtigen Reihenfolge
hintereinander schreiben, um das zu erreichen, was du möchtest. Das
nennt man dann landläufig „Programm“.
Oliver
Probier dies mal aus:
Einfach in's C File reinhauen:
1
asm(".globl LedOn");
2
asm("LedOn = 0x0801001D");
3
voidLedOn(void);
Und dann in Main:
z.B:
1
voidmain(void)
2
{
3
LedOn();
4
}
Wie gesagt, bei C++ braucht es noch ein "extern C" in der
Funktionsdeklaration. Wenn das funktioniert (ich hab es nicht getestet,
aber es kompiliert und linkt sauber durch) dann kannst Du den oberen
Code Teil mit der Deklaration und dem festnageln der Funktion auf eine
feste Adresse in ein Header File schreiben und überall in Deinem
Projekt benutzen.
Gruß,
Nils
pegel schrieb:> so genau mache ich das auch.> Nur will ich nicht 0x1234567 eingeben, sondern die Adresse wo die> 0x1234567 drin steht.
Das geht leider nicht. So schlau ist der GCC Linker nicht. Sorry.
Oliver S. schrieb:> Eine indirekte Zuweisung „hole den Wert dazu aus einer Speicherstelle“> gibt es auf dieser Sprachebene nicht.
Das ist doch mal ein Wort.
Also werde ich einfach eine Adressen Tabelle mit fester Größe an den
Anfang des Bereiches legen und bei Bedarf neue Funktionen der Reihe nach
einfügen.
Dann bleiben alte Funktionsadressen erhalten und müssen nur einmal per
Hand eingetragen werden.
Problem gelöst!
pegel schrieb:> Oliver S. schrieb:>> Eine indirekte Zuweisung „hole den Wert dazu aus einer Speicherstelle“>> gibt es auf dieser Sprachebene nicht.>> Das ist doch mal ein Wort.
Ein falsches Wort.
1
void*table[10]=0x0800ABCD;//10 Funktionen
2
3
// die dritte ist die LedOn() Funktion
4
typedefuint32_tLedOn_t(uint32_targ1);
5
LedOn_t*LedOn=(LedOn_t*)(table[2]);
6
7
LedOn(1)
> Also werde ich einfach eine Adressen Tabelle mit fester Größe an den> Anfang des Bereiches legen und bei Bedarf neue Funktionen der Reihe> nach einfügen.> Dann bleiben alte Funktionsadressen erhalten und müssen nur einmal per> Hand eingetragen werden.
Bringt nur überhaupt nichts. Die Prototypen der Funktionen müssen
ohenhin bekannt sein. Es sei denn, sie haben alle den gleichen. Aber
wenn du die Prototypen im eigentlichen Zielprogramm kennen mußt, dann
kannst du auch die Adressen der Funktionen dort eintragen. Wenn du nur
Funktionen hinzufügst, ändern sich die alten Adressen auch nicht.
> Problem gelöst!
Welches "Problem" auch immer