#### 3.5.1 File layout

The mmo file contents is not partitioned into named sections as with e.g. ELF. Memory areas is formed by specifying the location of the data that follows. Only the memory area ‘`0x0000…00`’ to ‘`0x01ff…ff`’ is executable, so it is used for code (and constants) and the area ‘`0x2000…00`’ to ‘`0x20ff…ff`’ is used for writable data. See mmo section mapping.

There is provision for specifying “special data” of 65536 different types. We use type 80 (decimal), arbitrarily chosen the same as the ELF `e_machine` number for MMIX, filling it with section information normally found in ELF objects. See mmo section mapping.

Contents is entered as 32-bit words, xor:ed over previous contents, always zero-initialized. A word that starts with the byte ‘`0x98`’ forms a command called a ‘`lopcode`’, where the next byte distinguished between the thirteen lopcodes. The two remaining bytes, called the ‘`Y`’ and ‘`Z`’ fields, or the ‘`YZ`’ field (a 16-bit big-endian number), are used for various purposes different for each lopcode. As documented in http://mmix.cs.hm.edu/doc/mmixal.pdf, the lopcodes are:

`lop_quote`

  0x98000001. The next word is contents, regardless of whether it starts with 0x98 or not.

`lop_loc`

  0x9801YYZZ, where ‘`Z`’ is 1 or 2. This is a location directive, setting the location for the next data to the next 32-bit word (for Z = 1) or 64-bit word (for Z = 2), plus Y * 2^56. Normally ‘`Y`’ is 0 for the text segment and 2 for the data segment. Beware that the low bits of non- tetrabyte-aligned values are silently discarded when being automatically incremented and when storing contents (in contrast to e.g. its use as current location when followed by lop_fixo et al before the next possibly-quoted tetrabyte contents).

`lop_skip`

  0x9802YYZZ. Increase the current location by ‘`YZ`’ bytes.

`lop_fixo`

  0x9803YYZZ, where ‘`Z`’ is 1 or 2. Store the current location as 64 bits into the location pointed to by the next 32-bit (Z = 1) or 64-bit (Z = 2) word, plus Y * 2^56.

`lop_fixr`

  0x9804YYZZ. ‘`YZ`’ is stored into the current location plus 2 - 4 * YZ.

`lop_fixrx`

  0x980500ZZ. ‘`Z`’ is 16 or 24. A value ‘`L`’ derived from the following 32-bit word are used in a manner similar to ‘`YZ`’ in lop_fixr: it is xor:ed into the current location minus 4 * L. The first byte of the word is 0 or 1. If it is 1, then L = (lowest 24 bits of word) - 2^Z, if 0, then L = (lowest 24 bits of word).

`lop_file`

  0x9806YYZZ. ‘`Y`’ is the file number, ‘`Z`’ is count of 32-bit words. Set the file number to ‘`Y`’ and the line counter to 0. The next Z * 4 bytes contain the file name, padded with zeros if the count is not a multiple of four. The same ‘`Y`’ may occur multiple times, but ‘`Z`’ must be 0 for all but the first occurrence.

`lop_line`

  0x9807YYZZ. ‘`YZ`’ is the line number. Together with lop_file, it forms the source location for the next 32-bit word. Note that for each non-lopcode 32-bit word, line numbers are assumed incremented by one.

`lop_spec`

  0x9808YYZZ. ‘`YZ`’ is the type number. Data until the next lopcode other than lop_quote forms special data of type ‘`YZ`’. See mmo section mapping.

  Other types than 80, (or type 80 with a content that does not parse) is stored in sections named `.MMIX.spec_data.n` where n is the ‘`YZ`’-type. The flags for such a sections say not to allocate or load the data. The vma is 0. Contents of multiple occurrences of special data n is concatenated to the data of the previous lop_spec ns. The location in data or code at which the lop_spec occurred is lost.

`lop_pre`

  0x980901ZZ. The first lopcode in a file. The ‘`Z`’ field forms the length of header information in 32-bit words, where the first word tells the time in seconds since ‘`00:00:00 GMT Jan 1 1970`’.

`lop_post`

  0x980a00ZZ. Z > 32. This lopcode follows after all content-generating lopcodes in a program. The ‘`Z`’ field denotes the value of ‘`rG`’ at the beginning of the program. The following 256 - Z big-endian 64-bit words are loaded into global registers ‘`$G`’ … ‘`$255`’.

`lop_stab`

  0x980b0000. The next-to-last lopcode in a program. Must follow immediately after the lop_post lopcode and its data. After this lopcode follows all symbols in a compressed format (see Symbol-table).

`lop_end`

  0x980cYYZZ. The last lopcode in a program. It must follow the lop_stab lopcode and its data. The ‘`YZ`’ field contains the number of 32-bit words of symbol table information after the preceding lop_stab lopcode.

Note that the lopcode "fixups"; `lop_fixr`, `lop_fixrx` and `lop_fixo` are not generated by BFD, but are handled. They are generated by `mmixal`.

This trivial one-label, one-instruction file:

     :Main TRAP 1,2,3

can be represented this way in mmo:

     0x98090101 - lop_pre, one 32-bit word with timestamp.
     <timestamp>
     0x98010002 - lop_loc, text segment, using a 64-bit address.
                  Note that mmixal does not emit this for the file above.
     0x00000000 - Address, high 32 bits.
     0x00000000 - Address, low 32 bits.
     0x98060002 - lop_file, 2 32-bit words for file-name.
     0x74657374 - "test"
     0x2e730000 - ".s\0\0"
     0x98070001 - lop_line, line 1.
     0x00010203 - TRAP 1,2,3
     0x980a00ff - lop_post, setting $255 to 0.
     0x00000000
     0x00000000
     0x980b0000 - lop_stab for ":Main" = 0, serial 1.
     0x203a4040   See Symbol-table.
     0x10404020
     0x4d206120
     0x69016e00
     0x81000000
     0x980c0005 - lop_end; symbol table contained five 32-bit words.