About

6.4 MARIE Assembly Language & the Two-Pass Assembler

Theory: MARIE Assembly Language & the Two-Pass Assembler

Mnemonics vs Machine Code

The CPU only understands machine code: bit patterns such as 0001 0001 0000 0100. Humans write assembly language: one mnemonic instruction per line, such as Load 104. Each assembly instruction corresponds to exactly one machine instruction. An assembler is the program that translates assembly into machine code.

LevelExample (A=B+CA = B + C)
High-level languageA = B + C; (one statement, many machine instructions)
MARIE assemblyLoad B / Add C / Store A
MARIE machine code (hex)e.g. 1105 / 3106 / 2104

Different architectures use different mnemonics and formats for the same operation, which is why assembly is not portable.

Anatomy of a MARIE Source Line

Label,  Mnemonic  Operand    / comment
Loop,   Load      Count      / AC <- Count
PartRules
Label (optional)a name followed by a comma; it stands for the address of this line
Mnemonican instruction (Load, Add, Skipcond, …) or a directive (ORG, DEC, HEX, END)
Operanda label or a hex address for instructions; a number for DEC/HEX; none for Input, Output, Halt, Clear
Commenteverything after / is ignored by the assembler

Directives (pseudo-instructions)

Directives tell the assembler what to do; they are not translated into CPU instructions themselves.

DirectiveMeaningExampleProduces
ORG nstart placing code at hex address nORG 100(nothing; sets the location counter to 100)
DEC na data word given in decimalDEC -23FFE9
HEX na data word given in hexHEX 00230023
ENDend of the programEND(nothing)

Mini-example

X, DEC 35 reserves one word labelled X containing 35=00231635 = \text{0023}_{16}. Y, DEC -23 stores the two’s complement of 23: 23=001723 = \text{0017} → invert → FFE8 → +1 → FFE9.

Data must be placed after the Halt (or otherwise out of the instruction stream). The CPU cannot tell data from instructions: if execution runs into DEC 35 it will happily execute 0023 as JnS 023.

The Two-Pass Assembler

Labels can be used before they are defined (a forward reference: Load X appears before the line X, DEC 35). So the assembler cannot finish line 1 until it has seen the whole program. The solution is to read the source twice.

Pass 1: build the symbol table.

  1. Set the location counter (LC) from ORG (default 0).
  2. For each line: if it has a label, record label → LC in the symbol table. Translate the mnemonic into its opcode (partial code; the address is left blank if it is a label). Increment LC by 1 (every instruction and every DEC/HEX takes one word).

Pass 2: complete the code. 3. For each line: replace each label operand by its address from the symbol table, convert DEC/HEX constants to 16-bit hex, and output the finished machine word.

Mini-example (as in the lecture)

        ORG 100
        Load X
        Add Y
        Store Z
        Halt
X,      DEC 35
Y,      DEC -23
Z,      HEX 0000
        END

Pass 1: LC runs 100, 101, … ; labels seen at 104, 105, 106 → symbol table X = 104, Y = 105, Z = 106. Partial code: 1 ???, 3 ???, 2 ???, 7000, … Pass 2: fill in → 1104, 3105, 2106, 7000, 0023, FFE9, 0000. This is exactly the addition program of 6.3.

Input and Output

Input copies a value typed by the user into the AC (AC ← InREG); Output displays the AC (OutREG ← AC). Neither uses its address field.

Mini-example

Read two numbers and print the second minus the first:

        ORG 100
        Input       / AC <- first number
        Store A
        Input       / AC <- second number
        Subt A      / AC <- second - first
        Output
        Halt
A,      DEC 0

Hex: 5000 2106 5000 4106 6000 7000 0000. With inputs 9 then 30 it outputs 30−9=2130 - 9 = 21 (hex 0015).

Translating Control Structures

MARIE has only one conditional instruction, Skipcond, which skips the next instruction. Every if and loop is built as “test, Skipcond, Jump”:

  1. Compute a value in the AC whose sign answers the question (usually by subtracting: X − Y).
  2. Skipcond with the condition under which you want to stay on the straight path.
  3. The next line is a Jump to the “other” path; it is skipped when the condition holds.
High-level conditionCompute in ACSkipcond to enter the body
X >\gt YX − YSkipcond 800 (skip the jump if X − Y >\gt 0)
X <\lt YX − YSkipcond 000
X = YX − YSkipcond 400
X >\gt 1X − 1Skipcond 800

For X≥YX \ge Y (or any “not” condition), test the opposite condition, X<YX \lt Y, and simply swap which code is the THEN part and which is the ELSE part.

If / else template

        Load X
        Subt Y
        Skipcond 800    / X - Y > 0 ?  -> skip the Jump, run THEN
        Jump Else
Then,   ...             / THEN part
        Jump EndIf
Else,   ...             / ELSE part
EndIf,  ...

While-loop template (while X < Y do body)

While,  Load X
        Subt Y
        Skipcond 000    / X - Y < 0 ?  -> skip the Jump, run the body
        Jump EndW
        ...             / body
        Jump While
EndW,   ...

Counting-loop template (repeat N times, N counts down)

Loop,   Load N
        Skipcond 800    / N > 0 ?  -> skip the Jump, run the body
        Jump Done
        ...             / body
        Load N
        Subt One
        Store N
        Jump Loop
Done,   ...

Subroutines with JnS and JumpI

A subroutine starts with one word reserved for the return address, followed by its code, and ends with JumpI on that word:

        JnS Sub         / M[Sub] <- return address, PC <- Sub + 1
        ...             / execution resumes here
Sub,    HEX 0000        / holds the return address
        ...             / subroutine body (starts at Sub + 1)
        JumpI Sub       / PC <- M[Sub]: return

Parameters are passed through agreed memory locations (MARIE has no stack). Remember that JnS overwrites the AC.


Worked Examples

Exercise 1

Assemble the labelled addition program (as in the lecture) by hand using the two-pass method. Show the symbol table after pass 1, the partial code, and the final hex code. What is in Z after the program runs?

        ORG 100
        Load X
        Add Y
        Store Z
        Halt
X,      DEC 35
Y,      DEC -23
Z,      HEX 0000
        END
Show solution ↓
Solution

Pass 1: walk the lines with the location counter starting at 100 (hex).

LCLabelSourcePartial code
100Load X1 ???
101Add Y3 ???
102Store Z2 ???
103Halt7000
104XDEC 35(constant)
105YDEC -23(constant)
106ZHEX 0000(constant)

Symbol table

SymbolAddress
X104
Y105
Z106

Pass 2: substitute addresses and convert constants. 35=32+3=231635 = 32 + 3 = \text{23}_{16} → 0023. −23-23: 23=001723 = \text{0017}, invert → FFE8, +1 → FFE9.

AddressSourceHex
100Load X1104
101Add Y3105
102Store Z2106
103Halt7000
104X, DEC 350023
105Y, DEC -23FFE9
106Z, HEX 00000000

Run: AC = 0023 → AC = 0023 + FFE9 = 000C → Z = 000C = 12 ✓ (35−2335 - 23).

Exercise 2

Write a MARIE program for

if (A < B) Max = B; else Max = A;
output Max;

with A = 7, B = 12, starting at ORG 100. Hand-assemble it, give the symbol table and trace the execution.

Show solution ↓
Solution

A<B  ⟺  A−B<0A \lt B \iff A - B \lt 0, so compute A − B and use Skipcond 000 to enter the THEN part.

AddrLabelSourceHex
100Load A110C
101Subt B410D
102Skipcond 0008000
103Jump Else9107
104Load B110D
105Store Max210E
106Jump Done9109
107Else,Load A110C
108Store Max210E
109Done,Load Max110E
10AOutput6000
10BHalt7000
10CA,DEC 70007
10DB,DEC 12000C
10EMax,DEC 00000

Symbol table: Else = 107, Done = 109, A = 10C, B = 10D, Max = 10E.

Trace

AddrInstructionAC afterNote
100Load A0007
101Subt BFFFB7−12=−57 - 12 = -5
102Skipcond 000FFFBAC <0\lt 0 → skip 103
104Load B000C
105Store Max000CMax = 000C
106Jump Done000CPC ← 109
109Load Max000C
10AOutput000Cprints 12
10BHalt

Output 12 = max(7, 12) ✓.

Exercise 3

Write a counting loop that computes Sum=5+4+3+2+1\text{Sum} = 5 + 4 + 3 + 2 + 1 (count N down from 5 to 0) and outputs it. Start at ORG 100. Give the hex code, symbol table, and the values of N and Sum at the top of each iteration.

Show solution ↓
Solution
        ORG 100
Loop,   Load N
        Skipcond 800    / N > 0 ? skip the Jump
        Jump Done
        Load Sum
        Add N           / Sum = Sum + N
        Store Sum
        Load N
        Subt One        / N = N - 1
        Store N
        Jump Loop
Done,   Load Sum
        Output
        Halt
N,      DEC 5
Sum,    DEC 0
One,    DEC 1
AddrSourceHexAddrSourceHex
100Loop, Load N110D108Store N210D
101Skipcond 8008800109Jump Loop9100
102Jump Done910A10ADone, Load Sum110E
103Load Sum110E10BOutput6000
104Add N310D10CHalt7000
105Store Sum210E10DN, DEC 50005
106Load N110D10ESum, DEC 00000
107Subt One410F10FOne, DEC 10001

Symbol table: Loop = 100, Done = 10A, N = 10D, Sum = 10E, One = 10F.

IterationN at topSkip?Sum after body
15yes (5 >\gt 0)5
24yes9
33yes12
42yes14
51yes15
exit0no → Jump Done

Output: Sum = 15 = 000F ✓ (5⋅6/2=155 \cdot 6 / 2 = 15).

Exercise 4

Translate the while loop

while (X < Limit) X = X + X;
output X;

for X = 3, Limit = 20, starting at ORG 200. Give the hex code, symbol table and a trace of X.

Show solution ↓
Solution

Test X−Limit<0X - \text{Limit} \lt 0 with Skipcond 000.

AddrLabelSourceHex
200While,Load X120B
201Subt Limit420C
202Skipcond 0008000
203Jump EndW9208
204Load X120B
205Add X320B
206Store X220B
207Jump While9200
208EndW,Load X120B
209Output6000
20AHalt7000
20BX,DEC 30003
20CLimit,DEC 200014

Symbol table: While = 200, EndW = 208, X = 20B, Limit = 20C.

TestXX − LimitAC (hex)Skipcond 000New X
13−17FFEFskip → body6
26−14FFF2skip → body12
312−8FFF8skip → body24
42440004no skip → Jump EndW

Output 24 (hex 0018) ✓: the first doubling of 3 that is not below 20.

Exercise 5

MARIE has no multiply instruction. Write a program that computes Prod=X×Y\text{Prod} = X \times Y by repeated addition for X = 4, Y = 3 (ORG 100), assemble it, and trace it.

Show solution ↓
Solution

Add X to Prod, Y times (Y counts down):

AddrLabelSourceHex
100Loop,Load Y110E
101Skipcond 8008800
102Jump Done910A
103Load Prod110F
104Add X310D
105Store Prod210F
106Load Y110E
107Subt One4110
108Store Y210E
109Jump Loop9100
10ADone,Load Prod110F
10BOutput6000
10CHalt7000
10DX,DEC 40004
10EY,DEC 30003
10FProd,DEC 00000
110One,DEC 10001

Symbol table: Loop = 100, Done = 10A, X = 10D, Y = 10E, Prod = 10F, One = 110.

PassY at testActionProd
13skip, add4
22skip, add8
31skip, add12
40Jump Done12

Output 12 (000C) = 4×34 \times 3 ✓.

Exercise 6

Write a subroutine Double that doubles the value in location Temp, and a main program that copies Num = 21 to Temp, calls Double with JnS, then outputs Temp. Assemble at ORG 100, give the symbol table and trace the call and return.

Show solution ↓
Solution
AddrLabelSourceHex
100Load Num1106
101Store Temp2107
102JnS Double0108
103Load Temp1107
104Output6000
105Halt7000
106Num,DEC 210015
107Temp,DEC 00000
108Double,HEX 00000000
109Load Temp1107
10AAdd Temp3107
10BStore Temp2107
10CJumpI DoubleC108

Symbol table: Num = 106, Temp = 107, Double = 108.

Trace

AddrInstructionEffect
100Load NumAC = 0015
101Store TempTemp = 0015
102JnS DoublePC was 103 → M[108] = 0103; AC = 108 + 1 = 0109; PC = 109
109Load TempAC = 0015
10AAdd TempAC = 002A
10BStore TempTemp = 002A
10CJumpI DoublePC ← M[108] = 103 (return)
103Load TempAC = 002A
104Outputprints 42
105Halt

Output 42 = 2×212 \times 21 ✓. Note JnS encodes as 0108 because its opcode is 0.

Exercise 7

Use AddI and a pointer to add the four array elements 10, 15, 20, 25 stored from address 112, starting at ORG 100. Give the hex code and symbol table and trace Ptr, Ctr and Sum.

Show solution ↓
Solution

Ptr holds the address of the current element; AddI Ptr adds the element Ptr points to. Ctr counts down from 4; Skipcond 400 leaves the loop when Ctr reaches 0.

AddrLabelSourceHex
100Loop,Load Sum110F
101AddI PtrB10E
102Store Sum210F
103Load Ptr110E
104Add One3111
105Store Ptr210E
106Load Ctr1110
107Subt One4111
108Store Ctr2110
109Skipcond 4008400
10AJump Loop9100
10BLoad Sum110F
10COutput6000
10DHalt7000
10EPtr,HEX 1120112
10FSum,DEC 00000
110Ctr,DEC 40004
111One,DEC 10001
112Arr,DEC 10000A
113DEC 15000F
114DEC 200014
115DEC 250019

Symbol table: Loop = 100, Ptr = 10E, Sum = 10F, Ctr = 110, One = 111, Arr = 112.

IterationPtr (before)M[Ptr]Sum afterCtr afterSkipcond 400
11121010 (000A)3no skip → Jump Loop
21131525 (0019)2no skip
31142045 (002D)1no skip
41152570 (0046)0skip the Jump

Output 70 (0046) ✓ =10+15+20+25= 10 + 15 + 20 + 25.