Skip to content

Assign

Level: 201 · for anyone with a hex editor open

One line: X[i] = Operand copies one number into every value, so the bytes it writes are decided before it runs — Treat Data As says how many bytes one copy fills and the Endian toggle says their order — which is why Assign 0xFEFF to a Short writes a byte order mark and Assign 0 with Operand Step 1 writes a code-page chart.

What the dialog does

010 Editor's manual ↗ gives Assign the shortest line in the list, X[i] = Operand, and the dialog's Description box repeats it. No value is read: what the range held before makes no difference to the result. That makes Assign the cleanest place to watch the other settings work, because the formula cannot hide them — the operand is a number, and a number becomes bytes only after the two decisions Hex: a number, or a picture of bytes is about, a width and an order. The chapter page covers each control once.

In Python

Verified output of assign_py.py — regenerated by tools/run_examples.py, never hand-typed.

1. ONE OPERAND, FOUR PATTERNS
------------------------------------------------------------------------
   Assign 0x41 over the same eight zero bytes, four ways. The formula
   is the same every time; how many bytes one copy fills, and in which
   order, is not.

     Unsigned Byte            41 41 41 41 41 41 41 41
     Unsigned Short, little   41 00 41 00 41 00 41 00
     Unsigned Short, big      00 41 00 41 00 41 00 41
     Unsigned Int, little     41 00 00 00 41 00 00 00

   The second row is 'A' and a NUL, four times -- which is what
   UTF-16LE writes for AAAA:

     .decode('utf-16-le')                'AAAA'
     == 'AAAA'.encode('utf-16-le')       True

2. ASSIGN FEFF TO ONE SHORT AND YOU HAVE WRITTEN A BOM
------------------------------------------------------------------------
   U+FEFF, the byte order mark, is a 16-bit value. Assign it to the
   first Unsigned Short of a file and the Endian toggle picks which of
   the two marks you wrote:

     little  ff fe   == codecs.BOM_UTF16_LE: True
     big     fe ff   == codecs.BOM_UTF16_BE: True

3. OPERAND STEP BUILDS THE TABLE EVERY CODE PAGE IS DRAWN ON
------------------------------------------------------------------------
   Assign 0 with Operand Step 1 over 256 bytes writes every byte value
   once, in order:

     the first eight   00 01 02 03 04 05 06 07
     the last eight    f8 f9 fa fb fc fd fe ff
     == bytes(range(256)): True

   Decode that file one byte at a time and count what each table calls
   a character:

     latin-1  256 of 256
     cp1252   251 of 256   refuses 81 8d 8f 90 9d
     ascii    128 of 256
     utf-8    128 of 256

4. THE TYPE DECIDES THE BYTES, NOT ONLY HOW MANY
------------------------------------------------------------------------
   Type 1 into the Operand box. What reaches the file depends on the
   type it is written as:

     Unsigned Byte          01
     Unsigned Int, little   01 00 00 00
     Unsigned Int, big      00 00 00 01
     Float, little          00 00 80 3f
     Double, little         00 00 00 00 00 00 f0 3f

   A Float or a Double is not the integer in more bytes. It is the
   same number in a different notation, and none of its bytes is 01.

5. OPERAND STEP ON A SHORT COUNTS IN CHARACTERS
------------------------------------------------------------------------
   Assign 0x41 with Operand Step 1, as a little-endian Unsigned Short,
   over eight bytes:

     41 00 42 00 43 00 44 00   .decode('utf-16-le') -> 'ABCD'

One operand, many patterns

Section 1 is the whole page in eight bytes. Typed as 0x41, the operand is 65 whatever the type. Written as an Unsigned Byte it is one byte, 41, and fills the range eight times; written as a little-endian Unsigned Short it is 41 00, which is A in UTF-16LE, so the same range now reads AAAA to a UTF-16 decoder and A, NUL, A, NUL to everything else.

Section 2 is the same fact with a famous number. U+FEFF is a 16-bit value, so Assign 0xFEFF to the first Unsigned Short of a file writes a byte order mark: FF FE under Little Endian and FE FF under Big Endian, byte for byte what Python's codecs.BOM_UTF16_LE and codecs.BOM_UTF16_BE hold. The toggle chooses which mark, not whether.

Section 4 is the one to remember when the type is Float or Double. A 1 typed into the box does not become 01 padded to four bytes; it becomes the IEEE 754 encoding of 1.0, 00 00 80 3F, and none of those bytes is 01. Treat Data As decides the notation a number is written in, not only its size.

Operand Step writes a table

With Operand Step 1, Assign stops being a fill and becomes a counter. Over 256 bytes from 0 it writes every byte value once, in order — the file every code page chart is a picture of — and section 3 hands that file to four decoders one byte at a time: Latin-1 accepts all 256, Windows-1252 refuses the five values it leaves empty, 81 8D 8F 90 9D, and ASCII and UTF-8 accept only the first 128 on their own. Section 5 steps a Short from 0x41 and gets ABCD in UTF-16LE: a step on a two-byte value counts in characters.

What the manual does not say

  • What Assign writes when the operand does not fit the type — 300 as an Unsigned Byte, or −1 as an Unsigned Short. The program never tries.
  • What happens when Operand Step carries the operand past the top of the type partway through a range.
  • What becomes of the last few bytes of a range too short to hold a whole value.

The chapter page lists the open questions for all twenty operations.

If you are coming from Python or ABAP

Python. There is no fill-with-a-number call, and the reason is this page: a number has to become bytes before it can fill anything, and that is the step where the width and the order are chosen. struct.pack('<H', 0xFEFF) is section 2's first row, struct.pack('<4H', 0x41, 0x42, 0x43, 0x44) is section 5, and bytes(range(256)) is the Operand Step table. To write one into the middle of a bytearray, assign it to a slice of the same length.

ABAP. (Not machine-checked — CI cannot run ABAP.) Assigning an i to an x field is Assign with the Endian toggle on Big: the integer's four bytes are placed right-justified in big-endian order, and padded or cut on the left ↗, so assigning 65 to a TYPE x LENGTH 2 field writes 00 41 on every application server. No assignment writes little-endian; a little-endian field is written by reversing the bytes yourself, which is Swap Bytes.

Try it

  1. In a copy of any file, select sixteen bytes and Assign 0x41 with Operand Step 1 as Unsigned Short. Set View > Character Set to Unicode and read the range, then flip View > Endian and read it again.
  2. Assign 0xFEFF to the first two bytes of a UTF-16 text file saved without a mark, and open it in two editors you use. Then do it with the other Endian setting and see which of them notice.
  3. Build section 3's table in 256 bytes of a scratch file and step through View > Character Set, counting in each how many of the 256 draw as a character.
  4. Assign 1 to the same four bytes as Float and then as Unsigned Int, and read each result in the Inspector as the other type.

See also