[M3devel] packing problem… how exactly does modula-3 pack data into records??

Rodney M. Bates rodney_bates at lcwb.coop
Wed Jan 18 20:54:03 CET 2012

On 01/18/2012 08:10 AM, Dragiša Durić wrote:
> As per subject… I would like to pack this:
>    TSPacketHeader = RECORD
>      sync: BITS 8 FOR File.Byte;   (* Always 0x47 *)
>      tErrInd,                      (* Transport Error Indicator *)
>      pusi: BITS 1 FOR BOOLEAN;     (* Payload Unit Start Indicator *)
>      transPrio: BITS 1 FOR [0..1];
>      pid: BITS 13 FOR PID;
>      transScramControl: BITS 2 FOR [0..3]; (* 00 means no scrambling *)
>      afc: BITS 2 FOR [0..3]; (* 01 - no adaptation field, payload only *)
>      cc: BITS 4 FOR Nibble;
>    END;
> My data, pusi is TRUE, sync is 0x47, pid is 4129 (0x1021), cc is 5 and afc is 0x1.Rest is zeros.
> What I get is:
> 0000 1010 1000 0001 0101 0100
> last five bits of pid; one bit for transPrio, one bit for pusi (TRUE), one bit for tErrInd;
> first eight bits of pid
> four bits of cc; two bits of abc; two bits for transScramControl
> a mess. with pid being most special sort of it :).
> Is this excected/normal? Wasn't whole idea os packing data into record about packing bits left-right-until-spent?
> TIA,
> dd

Hmm, this smells very strongly of a little-endian problem.

You didn't say how you got the actual bit contents you give.  It has only 24 bits,
though the record has 32.

Here is a possible explanation.

1) The packed record is laid out in little-endian, i.e. right-to-left.
2) The value you give is byte 1, byte 2, byte 3 of the word, numbering
    bytes right-to-left, as in little endian.
This interpretation correctly predicts your actual value.

The language doesn't say anything about endianness or order of field layout
in a record with packed fields, in the section on packed types.  However, I
think I recall there are other places where the language specifically calls
for little-endian numbering, regardless of the actual target machine.  I don't
remember where right off hand.

It may be that the actual rule is to do it the way the target machine numbers
things.  The apparent assumption is that packed records are unavoidably
target-dependent in other ways anyway.

I agree this example is a mess, but I think the mess is mostly inherited from the
mess that so-called "little endian" is.  It's inconsistent.  R2L within the bits
of a native machine word, L2R between words of an array or record, L2R when there
are arrays of bytes, L2R in machine code, L2R in byte-oriented I/O operations.
Then we have deeper mixups, e.g. an array of 16-bit elements.

I guess we at least need to document what the compiler actually does.

More information about the M3devel mailing list