asm indirekte Addresse zuweisen

Gast #6909228
Lesenswert?

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.
#6909243
Lesenswert?

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
#6909276
Lesenswert?

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.
Gast #6909286
Lesenswert?

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.
Gast #6909303
Lesenswert?

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" void myCrazyFunc (int a, int b);

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
#6909323
Lesenswert?

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
Gast #6909325
Lesenswert?

Probier dies mal aus:

Einfach in's C File reinhauen:
1
asm (".globl LedOn");
2
asm ("LedOn = 0x0801001D");
3
void LedOn (void);

Und dann in Main:

z.B:
1
void main (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
Gast #6909334
Lesenswert?

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!
#6909399
Lesenswert?

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
typedef uint32_t LedOn_t (uint32_t arg1); 
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren