Page 1 of 1
STRUCTURE ALIGNMENT
Posted: Fri Jul 22, 2011 4:29 pm
by 4GlCoder
Ok, I have a structure
ZAP* = RECORD
filename : ARRAY 11 OF SYSTEM.BYTE;
attr : SYSTEM.BYTE;
NTRes : SYSTEM.BYTE;
END;
While compiling I get the following: !Length rounded up
Do I run in trouble when reading this from an existing file ?
I need byte aligment and not INTEGER/WORD alignment.
Re: STRUCTURE ALIGNMENT
Posted: Sat Jul 23, 2011 4:03 am
by cfbsoftware
Arrays and records in ARM Oberon-07 are allocated memory in multiples of four bytes. You can use SYSTEM.SIZE to find out how much storage each data type occupies. e.g. SYSTEM.SIZE(ZAP) returns 20 (12 + 4 + 4).
If you are reading data from a binary file created on another system you will need to treat it as a bytestream and do the byte packing yourself. Depending on the origin of the file you may need to consider endian issues as well as alignment.
What you can do is pass a variable of type ZAP to a procedure as a generic output parameter declared as ARRAY OF BYTE. The procedure would input 13 bytes from the file and transfer them to the appropriate bytes of the output parameter.
Examples of the use of ARRAY OF BYTE can be seen in the Astrobe library modules I2C.mod, SPI.mod and Traps.mod.
Re: STRUCTURE ALIGNMENT
Posted: Sat Jan 19, 2013 4:41 am
by Alexander Shiryaev
I use the following module:
Code: Select all
MODULE MemFormatters;
(*
A. V. Shiryaev, 2013.01
LE: Little-Endian
BE: Big-Endian
*)
IMPORT SYSTEM;
(* Write *)
PROCEDURE WriteIntLE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
BEGIN
a[w] := CHR(x);
a[w + 1] := CHR(x DIV 100H);
a[w + 2] := CHR(x DIV 10000H);
a[w + 3] := CHR(x DIV 1000000H);
INC(w, 4)
END WriteIntLE;
PROCEDURE WriteIntBE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
BEGIN
a[w] := CHR(x DIV 1000000H);
a[w + 1] := CHR(x DIV 10000H);
a[w + 2] := CHR(x DIV 100H);
a[w + 3] := CHR(x);
INC(w, 4)
END WriteIntBE;
PROCEDURE WriteInt16LE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
BEGIN
a[w] := CHR(x);
a[w + 1] := CHR(x DIV 100H);
INC(w, 2)
END WriteInt16LE;
PROCEDURE WriteInt16BE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
BEGIN
a[w] := CHR(x DIV 100H);
a[w + 1] := CHR(x);
INC(w, 2)
END WriteInt16BE;
PROCEDURE WriteInt8* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: INTEGER);
BEGIN
a[w] := CHR(x);
INC(w)
END WriteInt8;
PROCEDURE WriteRealLE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: REAL);
BEGIN
WriteIntLE(a, w, SYSTEM.VAL(INTEGER, x))
END WriteRealLE;
PROCEDURE WriteRealBE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: REAL);
BEGIN
WriteIntBE(a, w, SYSTEM.VAL(INTEGER, x))
END WriteRealBE;
PROCEDURE WriteSetLE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: SET);
BEGIN
WriteIntLE(a, w, SYSTEM.VAL(INTEGER, x))
END WriteSetLE;
PROCEDURE WriteSetBE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: SET);
BEGIN
WriteIntBE(a, w, SYSTEM.VAL(INTEGER, x))
END WriteSetBE;
PROCEDURE WriteSet16LE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: SET);
BEGIN
WriteInt16LE(a, w, SYSTEM.VAL(INTEGER, x))
END WriteSet16LE;
PROCEDURE WriteSet16BE* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: SET);
BEGIN
WriteInt16BE(a, w, SYSTEM.VAL(INTEGER, x))
END WriteSet16BE;
PROCEDURE WriteSet8* (VAR a: ARRAY OF CHAR; VAR w: INTEGER; x: SET);
BEGIN
WriteInt8(a, w, SYSTEM.VAL(INTEGER, x))
END WriteSet8;
(* Read *)
PROCEDURE ReadIntLE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]) + ORD(a[r + 1]) * 100H + ORD(a[r + 2]) * 10000H + ORD(a[r + 3]) * 1000000H;
INC(r, 4)
END ReadIntLE;
PROCEDURE ReadIntBE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]) * 1000000H + ORD(a[r + 1]) * 10000H + ORD(a[r + 2]) * 100H + ORD(a[r + 3]);
INC(r, 4)
END ReadIntBE;
PROCEDURE ReadUInt16LE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]) + ORD(a[r + 1]) * 100H;
INC(r, 2)
END ReadUInt16LE;
PROCEDURE ReadUInt16BE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]) * 100H + ORD(a[r + 1]);
INC(r, 2)
END ReadUInt16BE;
PROCEDURE ReadSInt16LE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]) + ORD(a[r + 1]) * 100H;
INC(r, 2);
IF x >= 32768 THEN x := x - 65536 END
END ReadSInt16LE;
PROCEDURE ReadSInt16BE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]) * 100H + ORD(a[r + 1]);
INC(r, 2);
IF x >= 32768 THEN x := x - 65536 END
END ReadSInt16BE;
PROCEDURE ReadUInt8* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]);
INC(r)
END ReadUInt8;
PROCEDURE ReadSInt8* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: INTEGER);
BEGIN
x := ORD(a[r]);
INC(r);
IF x >= 128 THEN x := x - 256 END
END ReadSInt8;
PROCEDURE ReadRealLE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: REAL);
VAR t: INTEGER;
BEGIN
ReadIntLE(a, r, t);
x := SYSTEM.VAL(REAL, t)
END ReadRealLE;
PROCEDURE ReadRealBE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: REAL);
VAR t: INTEGER;
BEGIN
ReadIntBE(a, r, t);
x := SYSTEM.VAL(REAL, t)
END ReadRealBE;
PROCEDURE ReadSetLE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: SET);
VAR t: INTEGER;
BEGIN
ReadIntLE(a, r, t);
x := SYSTEM.VAL(SET, t)
END ReadSetLE;
PROCEDURE ReadSetBE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: SET);
VAR t: INTEGER;
BEGIN
ReadIntBE(a, r, t);
x := SYSTEM.VAL(SET, t)
END ReadSetBE;
PROCEDURE ReadSet16LE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: SET);
VAR t: INTEGER;
BEGIN
ReadUInt16LE(a, r, t);
x := SYSTEM.VAL(SET, t)
END ReadSet16LE;
PROCEDURE ReadSet16BE* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: SET);
VAR t: INTEGER;
BEGIN
ReadUInt16BE(a, r, t);
x := SYSTEM.VAL(SET, t)
END ReadSet16BE;
PROCEDURE ReadSet8* (a: ARRAY OF CHAR; VAR r: INTEGER; VAR x: SET);
BEGIN
x := SYSTEM.VAL(SET, ORD(a[r]));
INC(r)
END ReadSet8;
END MemFormatters.