Verschiedene Variablen auf gleiche Speicherstelle

Rund um die LCL und andere Komponenten

Verschiedene Variablen auf gleiche Speicherstelle

Beitragvon Timm Thaler » 5. Mär 2018, 02:50 Verschiedene Variablen auf gleiche Speicherstelle

Ich habe gerade eine Denkblockade: Wie lege ich verschiedene Variablen auf die gleiche Speicherstelle?

Ich habe 2 Variablen
hh, mm : uint8;
und 1 Variable
time : uint16;

In hh und mm werden Stunden und Minuten als gepackte BCD-Zahl gespeichert, das obere Nibble enthält also die Zehner, das untere Nibble die Einer.

Jetzt möchte ich die Variable time so ablegen, dass deren oberes Byte hh, das untere Byte mm enthält. Ich weiss dass das geht, aber ich komme gerade nicht drauf wie. Ich brauche das für den einfachen Vergleich von Uhrzeiten.

Ich könnte hh,mm auch als Record anlegen, würde das was bringen?

Compiliert werden soll für Embedded AVR, aber das sollte ja egal sein.
Timm Thaler
 
Beiträge: 708
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon mse » 5. Mär 2018, 08:05 Re: Verschiedene Variablen auf gleiche Speicherstelle

Timm Thaler hat geschrieben:Ich könnte hh,mm auch als Record anlegen, würde das was bringen?

Ja. "Offiziell" darfst du dich nicht darauf verlassen, dass zusammenhängend definierte Variablen auch zusammenhängend im Speicher abgelegt werden.
Code: Alles auswählen
 
type
 timeelementsty = packed record //little endian
  mm: uint8;
  hh: uint8;
 end;
 
 timety = packed record
  case integer of
   0: (elements: timeelementsty);
   1: (time: uint16);
  end;
 

Ungeprüft!
mse
 
Beiträge: 1989
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon fliegermichl » 5. Mär 2018, 08:51 Re: Verschiedene Variablen auf gleiche Speicherstelle

Hallo,

Das geht auch mit "absolute"
Code: Alles auswählen
 
var
 mm : uint8;
 hh : uint8;
 time : uint16 absolute mm;
 


das sorgt dafür, daß die Variable time an der Speicherstelle anfängt wie die mit absolute angegebene.
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon fliegermichl » 5. Mär 2018, 09:02 Re: Verschiedene Variablen auf gleiche Speicherstelle

bei der Lösung von mse ist es übrigens nicht nötig zwei records zu definieren.
Code: Alles auswählen
 
type
 TTimeRec = packed record
  case integer of
   0 : (mm, hh : uint8);
   1 : (time : uint16);
 end;
 


geht auch.
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 5. Mär 2018, 09:56 Re: Verschiedene Variablen auf gleiche Speicherstelle

fliegermichl hat geschrieben:Das geht auch mit "absolute"

Das ist dann aber nicht "offiziell", siehe oben.
mse
 
Beiträge: 1989
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon Timm Thaler » 5. Mär 2018, 10:25 Re: Verschiedene Variablen auf gleiche Speicherstelle

Hm, das "packed record" hab ich gesehen, war mir aber nicht sicher, ob das "meine" Lösung ist.

Ist das immer "little endian", oder nur auf dem AVR?

Ich hab auch was mit "references" gelesen, finde aber keine Infos dazu. Such mal nach "fpc reference"... hunderte Einträge, aber nicht zielführend. ;-)
Timm Thaler
 
Beiträge: 708
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon fliegermichl » 5. Mär 2018, 10:33 Re: Verschiedene Variablen auf gleiche Speicherstelle

Wenn ich mir die Freepascal Dokumentation anschaue, dann steht bei
6. The sixth form declares a variable (curterm6), and tells the compiler that it is stored in the same location as another variable (curterm1).

Ich kann nirgends "nicht offiziell" finden?!?
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 5. Mär 2018, 10:37 Re: Verschiedene Variablen auf gleiche Speicherstelle

Timm Thaler hat geschrieben:Ist das immer "little endian", oder nur auf dem AVR?

Die gezeigte Struktur ist für little endian. Universell:
Code: Alles auswählen
 
 timeelementsty = packed record
 {$ifdef endian_little}
  mm: uint8;
  hh: uint8;
 {$else}
  hh: uint8;
  mm: uint8;
 {$endif}
 end;
 

Ich hab auch was mit "references" gelesen, finde aber keine Infos dazu.

"references" als FPC Token? Das kenne ich nicht.
mse
 
Beiträge: 1989
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon mse » 5. Mär 2018, 10:42 Re: Verschiedene Variablen auf gleiche Speicherstelle

fliegermichl hat geschrieben:Ich kann nirgends "nicht offiziell" finden?!?

Man darf nicht erwarten, dass in
Code: Alles auswählen
 
var
 mm : uint8;
 hh : uint8;
 

"hh" ein Byte nach "mm" im Speicher liegt. Der Compiler kann Variablen im Speicher anlegen wie es ihm passt.
mse
 
Beiträge: 1989
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon Timm Thaler » 5. Mär 2018, 11:46 Re: Verschiedene Variablen auf gleiche Speicherstelle

mse hat geschrieben:"hh" ein Byte nach "mm" im Speicher liegt. Der Compiler kann Variablen im Speicher anlegen wie es ihm passt.


Und bei Records? Liegt bei
Code: Alles auswählen
timetype = packed record
  mm: uint8;
  hh: uint8;
 end;

hh immer direkt hinter mm, little endian vorausgesetzt?
Timm Thaler
 
Beiträge: 708
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

Beitragvon fliegermichl » 5. Mär 2018, 12:56 Re: Verschiedene Variablen auf gleiche Speicherstelle

Timm Thaler hat geschrieben:
mse hat geschrieben:"hh" ein Byte nach "mm" im Speicher liegt. Der Compiler kann Variablen im Speicher anlegen wie es ihm passt.


Und bei Records? Liegt bei
Code: Alles auswählen
timetype = packed record
  mm: uint8;
  hh: uint8;
 end;

hh immer direkt hinter mm, little endian vorausgesetzt?


Meiner Meinung nach ja, sonst würden Deklarationen wie array of record oder file of record nicht funktionieren.
fliegermichl
 
Beiträge: 202
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 5. Mär 2018, 17:02 Re: Verschiedene Variablen auf gleiche Speicherstelle

Timm Thaler hat geschrieben:Und bei Records? Liegt bei
Code: Alles auswählen
timetype = packed record
  mm: uint8;
  hh: uint8;
 end;

hh immer direkt hinter mm, little endian vorausgesetzt?

Immer, sogar unbhängig von little- oder big-endian.
mse
 
Beiträge: 1989
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon Mathias » 5. Mär 2018, 18:06 Re: Verschiedene Variablen auf gleiche Speicherstelle

Immer, sogar unbhängig von little- oder big-endian.

Bei diesem Code, könnte ich mir vorstellen, das es eine Rolle spielt.
Code: Alles auswählen
type
 TTimeRec = packed record
  case integer of
   0 : (mm, hh : uint8);
   1 : (time : uint16);
 end;

Noch ein Hinweis, wen man Daten mit Java austauscht, dann muss man little- und big-endian beachten.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4328
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon mse » 5. Mär 2018, 20:04 Re: Verschiedene Variablen auf gleiche Speicherstelle

Mathias hat geschrieben:
Immer, sogar unbhängig von little- oder big-endian.

Bei diesem Code, könnte ich mir vorstellen, das es eine Rolle spielt.
Code: Alles auswählen
type
 TTimeRec = packed record
  case integer of
   0 : (mm, hh : uint8);
   1 : (time : uint16);
 end;


Ja, dieser TTimeRec ist ausschliesslich für little-endian systeme.
mse
 
Beiträge: 1989
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon Timm Thaler » 5. Mär 2018, 21:40 Re: Verschiedene Variablen auf gleiche Speicherstelle

Bösartige Frage: Ist es möglich, den Record so zu modifizieren, dass ich drei Bytewerte habe, aber nur aus 2en ein Word mache?

hh, mm, ss : uint8 // so sieht meine Uhrzeit aus, die ich von der RTC bekomme
hhmm // das ist mein Zeitwert, auf den ich vergleiche

Ich würde also gern "time" so auf hh,mm,ss mappen, dass im Highbyte hh, im Lowbyte mm stehen und ss nicht beachtet wird.

Code: Alles auswählen
type
 TTimeRec = packed record
  case integer of
   0 : (ss, mm, hh : uint8);
   1 : (ss : uint8; time : uint16);
 end;
 

Wird sicher nicht gehen, weil ja der case so nicht funktioniert.

Code: Alles auswählen
type
 TTimeRec = packed record
  case integer of
   0 : (mm, hh, ss : uint8);
   1 : (time : uint16; ss : uint8);
 end;
 

Könnte vielleicht gehen, aber die Reihenfolge mm, hh, ss ist natürlich unschön.
Timm Thaler
 
Beiträge: 708
Registriert: 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded | 
CPU-Target: Raspberry Pi 3
Nach oben

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried