Forum: Compiler & IDEs Pointer frei einstellen


von Uwe P. Wettin (Gast)


Lesenswert?

Hallo,

ich möchte einen (4 Byte) Pointer beliebig im Adressbereich auf eine 
Adresse zeigen lassen. Bei der Übergabe einer (4 Byte) Int als Adresse 
an den Pointer beschwert sich der Compiler (int nicht möglich an int*).
Damit möchte ich eine flexible Funktion aufbauen, um diverse Register zu 
lesen und zu setzen.
Wie bekomme ich das hin? Hat jemand einen Schnipsel für mich? Die 
Register sind ebenfalls 4 Byte lang. STM32 mit IAR.

Gruß

von Nop (Gast)


Lesenswert?

Uwe P. Wettin schrieb:
> Bei der Übergabe einer (4 Byte) Int als Adresse
> an den Pointer beschwert sich der Compiler (int nicht möglich an int*).

Erstens nimmt man dafür den C99-Datentypen uintptr_t und nicht int. 
Zweitens castet man den dann zu einem Pointer auf den gewünschten 
Datentyp. Aufgepaßt, weil nicht alle Cortex-Ms unaligned access können.

von A. S. (Gast)


Lesenswert?

Das einfachste wäre ein int *p;

Per Default 0, und mit p[1000] oder int i=1000; p[i] greifst du 
int-alligned auf die Speicherstelle .... 4000 zu.

Ich hoffe, dass die Warnmeldung in echt aussagekräftiger war und "Cast" 
enthalten hat.

von Rolf M. (rmagnus)


Lesenswert?

Im einfachsten Fall etwa so:
1
meintyp* ptr = (meintyp*)0x12345;

Uwe P. Wettin schrieb:
> Bei der Übergabe einer (4 Byte) Int als Adresse
> an den Pointer beschwert sich der Compiler (int nicht möglich an int*).

Also ich kenne das so, dass der Compiler nicht sagt "nicht möglich", 
sondern "da fehlt ein Cast".

von S. R. (svenska)


Lesenswert?

Uwe P. Wettin schrieb:
> Wie bekomme ich das hin?

void* ptr = (void*)0x1234;

von Uwe P. Wettin (Gast)


Lesenswert?

So geht es nicht:

#include "stdint.h"
uintptr_t Adr ;
unsigned int * PAdr ;

void SetAdr(void){
// set Adr
...}

unsigned int Fetch(void){
PAdr = Adr ;   // Error uintptr_t cannot assigned unsigned int *
return(*PAdr) ;
}

void Store(unsigned int Val){
*Adr = Val ;
}

Wie kann ich PAdr setzen?

von S. R. (svenska)


Lesenswert?

Uwe P. Wettin schrieb:
> Wie kann ich PAdr setzen?

PAdr=(unsigned int*)Adr;

von and his name is (Gast)


Lesenswert?

Uwe P. Wettin schrieb:
> uintptr_t Adr ;

Uwe P. Wettin schrieb:
> void Store(unsigned int Val){
> *Adr = Val ;
> }

ähm, so wie es verstehe, ist das kein Zeiger, sondern eine Variable, die 
eine beliebige (aber gültige) Adresse aufnehmen kann. Also ist hier der 
Dereferenzierungsoperator nicht erforderlich (der Compiler musste sich 
hier aber melden).

Uwe P. Wettin schrieb:
> #include "stdint.h"

<stdint.h>

von Rolf M. (rmagnus)


Lesenswert?

and his name is schrieb:
> Uwe P. Wettin schrieb:
>> uintptr_t Adr ;
>
> Uwe P. Wettin schrieb:
>> void Store(unsigned int Val){
>> *Adr = Val ;
>> }
>
> ähm, so wie es verstehe, ist das kein Zeiger, sondern eine Variable, die
> eine beliebige (aber gültige) Adresse aufnehmen kann.

Genau. Es ist ein vorzeichenloser Integer, der groß genug ist, um einen 
beliebigen Zeigerwert verlustlos aufnehmen zu können, aber es ist selbst 
kein Zeiger. Ich würde aber auch als Parameter für Store einen uintptr_t 
nehmen und keinen unsigned int, denn bei letzterem kommt es auf die 
Plattform an, ob er einen Zeigerwert immer verlustlos aufnehmen kann. 
Genau deshalb gibt es ja uintptr_t.

> Also ist hier der Dereferenzierungsoperator nicht erforderlich (der Compiler
> musste sich hier aber melden).

Richtig.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Uwe P. Wettin schrieb:
> uintptr_t Adr ;
> unsigned int * PAdr ;

Eines davon ist überflüssig.

Entweder Adr und den Wert mit Cast als ptr lesen und schreiben

Oder PAdr und die Adresse mit Cast setzen

von Uwe P. Wettin (Gast)


Lesenswert?

Hallo,

es ist erstaunlich:
Kaum macht man es richtig, schon funktioniert es!

Vielen, vielen Dank für die ganzen Hinweise. Mädels, ihr seid echt nett 
zu mir.

Ich kann ganze Liebesbriefe in C schreiben, aber Pointer benutze ich 
leider viel zu selten. Und wenn, dann landet der Brief an der falschen 
Adresse :-(.

Aktuell sehe ich auf dem Terminal die gleichen Hex wie auf dem 
IAR-Disassembly-Window. Ein gutes Zeichen (genauer: viele gute Zeichen).

Anscheinend habe ich viel zu kompliziert gedacht, jedenfalls packe ich 
die ganzen Hinweise unters Kopfkissen und kaue sie bei Gelegenheit mal 
ruhig wieder.

Wenn ich darf, eine Frage hätte ich noch: Ich möchte über das Terminal 
einen Wert (einen Pointer) eingeben, zu dem das Programm springen soll 
(mit BX LR von dort retour). BL Pointer sozusagen, wobei BL in C und 
Pointer nicht relativ sein sollten. Gibt es sowas?

Nochmals vielen Dank !

von A. S. (Gast)


Lesenswert?

Uwe P. Wettin schrieb:
> zu dem das Programm springen soll

Funktionspointer? Allerdings nur zu Funktionen. Und da es meist nicht so 
viele gibt, mach dir lieber eine Liste und entsprechende Kommandos.

von Nop (Gast)


Lesenswert?

Es gibt in GCC eine C-Erweiterung, die sich "computed goto" nennt. Damit 
kann man beispielsweise goto-Labeladressen in einem Array speichern und 
dann über den Array-Index einen funktions-lokalen Sprung ausführen. Den 
Inhalt kann man natürlich auch mit uintptr_t speichern und ausgeben.

Wenn Du es noch drastischer brauchst, wären setjmp/longjmp (Standard-C) 
etwas. Das kann überall hinspringen, wo es schonmal war. Aber aufgepaßt, 
das funktioniert nur, solange Du im Calltree nicht abwärts springst. Ist 
zur Fehlerbehandlung gedacht, so macht man Exceptions in C.

von A. F. (artur-f) Benutzerseite


Lesenswert?

Uwe P. Wettin schrieb:
> Hallo,
>
> ich möchte einen (4 Byte) Pointer beliebig im Adressbereich auf eine
> Adresse zeigen lassen. Bei der Übergabe einer (4 Byte) Int als Adresse
> an den Pointer beschwert sich der Compiler (int nicht möglich an int*).
> Damit möchte ich eine flexible Funktion aufbauen, um diverse Register zu
> lesen und zu setzen.
> Wie bekomme ich das hin? Hat jemand einen Schnipsel für mich? Die
> Register sind ebenfalls 4 Byte lang. STM32 mit IAR.
>
> Gruß

Meinst du wirklich die uC Register oder Flash Speicher?

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.