Forum: Compiler & IDEs Pointer frei einstellen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Uwe P. Wettin (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht lesenswert
Im einfachsten Fall etwa so:
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)


Bewertung
2 lesenswert
nicht lesenswert
Uwe P. Wettin schrieb:
> Wie bekomme ich das hin?

void* ptr = (void*)0x1234;

von Uwe P. Wettin (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Uwe P. Wettin schrieb:
> Wie kann ich PAdr setzen?

PAdr=(unsigned int*)Adr;

von and his name is (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.