🡄 Previous

Next 🡆

Contents > General-purpose Computer > Assembly Language

Set Instructions

A set instruction assigns a register to an immediate (a constant):

InstructionNamePseudocodeOpcode
SEA immediateSet AA = immediate;50
SEB immediateSet BB = immediate;51
SMN immediateSet MNMN = immediate;2F

SEA and SEB assign an 8-bit immediate. And SMN assigns a 16-bit immediate.

They assemble to an opcode followed by the immediate byte or big-endian bytes.

The language accepts integer literal immediate values written in hexadecimal. As shown below, a byte literal contains two hex digits while a 16-bit word literal contains four hex digits.

SEA D3                  ; A = 0xD3;
SEB 7F                  ; B = 0x7F;
SMN 1234                ; MN = 0x1234;

The define directive equates a name with an integer literal:

define name value

A program can use defined names as immediate values:

define X D3             ; #define X 0xD3
define Y 7F             ; #define Y 0x7F
define Z 1234           ; #define Z 0x1234

SEA X                   ; A = X;
SEB Y                   ; B = Y;
SMN Z                   ; MN = Z;

A data region is a sequence of one or more integer literals not preceded by an instruction mnemonic. To reference a data region, a program prefaces it with a label, and it successively uses the label as a 16-bit immediate. The following example demonstrates this.

v: 00                   ; v = 0;

SMN v                   ; MN = &v;
LDA                     ; A = *MN;
INC                     ; ++A;
STA                     ; *MN = A;

The label v is a placeholder for the address of a single-byte data region that is initialized to zero. When used as an immediate, v resembles a byte variable. Lines 3–6 are equivalent to ++v;

The next example reserves and initializes an 8-element byte array, table, and a byte variable, index.

segment 0180

table:                  ; table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; 
01 02 04 08
10 20 40 80

index: 03               ; index = 0x03;

SMN index               ; MN = &index;
LDA                     ; A = *MN;
SMN table               ; MN = table;
TNB                     ; B = N;
ADD                     ; A += B;
TAN                     ; N = A;
LDA                     ; A = *MN;

Lines 9–15 are equivalent to:

A = table[index];

Or:

A = *(table + index);

However, without a carry flag, adding a 16-bit value to an 8-bit value is challenging. Instead, the code takes advantage of the segment directive, which has the following format.

segment address

It instructs the assembler to store bytes generated from subsequent code at the specified address. In this case, the effect is:

table = 0x0180;

Since the table is fully contained within the same 256-byte memory page, adding table and index does not produce a carry. The code offsets only the low-byte of the address.

To facilitate self-modifying code, a program can offset a label immediate by a positive or negative constant with the notation below.

label[+-]offset

The offset is a fixed integer value written in decimal.

The notation provides a way to modify the operand of an instruction, as seen in the following example.

SEA FF                  ; A = 0xFF;
SMN target+1            ; MN = target + 1;
STA                     ; *MN = A;

target:
SEB 00                  ; B = 0x00; // until replaced with 0xFF

The label target is a placeholder for the address of SEB's opcode byte. At runtime, lines 1–3 change SEB's operand byte by offsetting target by one. Consequentially, when the SEB instruction executes, it assigns B to FF rather than 00.

In summary, the operand of SMN can be any of the following.

SMN hex | label | label+offset | label-offset

The same applies to the branch instructions. They can use any of the above as the target. But it is rarely worthwhile to jump to a hex address or to a label offset by a constant.

🡄 Previous

Next 🡆