Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Stack Manipulation

Instructions for pushing constants and rearranging the top of the value stack: POP, PUSH1..PUSH8, SCLR, SWAP and COPY. Byte values, operand layouts and stack effects are in the Stack Manipulation section of the opcode reference. This page is mostly about the constant-pushing family, since the four rearrangement instructions (POP, SCLR, SWAP, COPY) are exactly what their names say: discard the top, clear everything, exchange the top two, or duplicate the top without consuming it. SWAP and COPY both error StackUnderflow rather than reading past an empty stack: a bare PUSH 1; SWAP needs a second element that is not there.

PUSH Size Selection

PUSH1 through PUSH8 are not mnemonics you write. In assembly, and through InstructionBuilder::push(), there is only PUSH <value>:

PUSH 42       ; assembler selects PUSH1 (fits in i8)
PUSH 1000     ; assembler selects PUSH2 (fits in i16)
PUSH -1       ; assembler selects PUSH1 (0xFF sign-extends to -1)

The assembler picks the narrowest PUSH1..PUSH8 variant that faithfully round-trips the literal, so small constants cost 2 bytes total (1 opcode + 1 operand byte) and the full 8-byte PUSH8 is only ever emitted for values that need all 64 bits. In the program above, PUSH 42 assembles to PUSH1 42 (0x2A), PUSH 1000 assembles to PUSH2 1000 (0x03E8), and PUSH -1 assembles to PUSH1 -1, whose single operand byte is 0xFF.

Writing PUSH1 directly does not work: it is not a recognised mnemonic, and the assembler rejects it with unknown mnemonic 'PUSH1'. PUSHC is accepted as an alias for PUSH and goes through the same size-selection path; there is no reason to prefer one over the other beyond house style.

The encoding itself is big-endian and sign-extended regardless of which PUSHn variant is chosen, which is what makes PUSH -1 a 1-byte operand rather than an 8-byte one: PUSH1 0xFF decodes as \(-1_{i64}\), not \(255_{i64}\), because the single byte is read as signed and then sign extended, not as an unsigned magnitude.