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.