Little Man Computer

A Little Man Computer (LMC) is a simulator which has many of the basic features of a modern computer that uses the Von Neumann architecture.

KS3 Computer Science

11-14 Years Old

48 modules covering EVERY Computer Science topic needed for KS3 level.

GCSE Computer Science

14-16 Years Old

45 modules covering EVERY Computer Science topic needed for GCSE level.

A-Level Computer Science

16-18 Years Old

66 modules covering EVERY Computer Science topic needed for A-Level.

GCSE Von Neumann Architecture (14-16 years)

  • An editable PowerPoint lesson presentation
  • Editable revision handouts
  • A glossary which covers the key terminologies of the module
  • Topic mindmaps for visualising the key concepts
  • Printable flashcards to help students engage active recall and confidence-based repetition
  • A quiz with accompanying answer key to test knowledge and understanding of the module

A-Level Assembly Language (16-18 years)

  • An editable PowerPoint lesson presentation
  • Editable revision handouts
  • A glossary which covers the key terminologies of the module
  • Topic mindmaps for visualising the key concepts
  • Printable flashcards to help students engage active recall and confidence-based repetition
  • A quiz with accompanying answer key to test knowledge and understanding of the module

Assembly Language programming using the LMC Simulator.


A Little Man Computer (LMC) is a simulator which has many of the basic features of a modern computer that uses the Von Neumann architecture (a central processing unit consisting of an arithmetic logic unit and registers, a control unit containing an instruction register and program counter, input and output mechanisms and RAM to store both data and instructions).
The LMC is based on the idea of a ‘Little Man’ acting like the control unit of a CPU, fetching instructions from RAM, decoding and executing them as well as managing the input and output mechanisms.
The two versions on this website can be programmed by using a basic set of 10 assembly code instructions which are then assembled into machine code (although in decimal not binary).
The LMC screen - click to enlarge

Understanding the LMC simulator

  • The 100 memory addresses in the computer memory are numbered 0 to 99 and can each contain a ‘machine code‘ instruction or data.
  • Each assembly language instruction is made up of a 3 letter mnemonic (which represents the operation code), usually followed by the memory address of the data the CPU is to act on (this is called absolute memory addressing).
  • Pressing the Assemble Program button translates the assembly language instructions into ‘machine code‘ and loads them into RAM. it also resets the Program Counter to zero.
  • The Input box allows the user to enter numerical data (-999 to 999) while a program is running and load it into the accumulator.
  • The Output box can output the contents of the accumulator while a program is running.
  • A RAM memory address that is used to store data can be given a meaningful label. Data can also be stored in these named address locations.
  • The results of any ADD or SUBTRACT instructions are stored in the accumulator .
  • The Program Counter stores the memory address of the instruction being carried out. It will automatically increment by 1 after each instruction is completed.
  • If the CPU receives an non-sequential instruction to branch (BRP, BRP or BRZ) then the Program Counter is set to the memory address of that instruction.
  • Branch instructions are set to branch to a labelled memory location.
  • To restart a program, the Program Counter is reset to 0.

When assembled, each assembly code instruction is converted into a 3 digit ‘machine code’ instruction (1 digit for the instruction and 2 for the memory address). The 3 digit ‘machine code’ instructions are then loaded into RAM, starting at memory address 0.
Any data is also loaded into memory at the memory address corresponding to the location of the data in the program (i.e. if the 5th line of the assembly language program was data then this data would be loaded into address 4, because memory address start at 0 not 1)
The ‘Little Man’ can then begin execution, starting with the instruction in RAM at memory address 0.
The ‘Little Man’ performs the following steps to execute a program:

  1. Check the Program Counter so it knows the memory address to look at.
  2. Fetch the instruction from the memory address that matches the program counter.
  3. Increment the Program Counter (so that it contains the memory address of the next instruction).
  4. Decode the instruction (includes finding the memory address for any data it refers to).
  5. If required by the instruction code, fetch the data from the memory address found in the previous step.
  6. Execute the instruction and if necessary set the Program Counter to match any branch instructions.

Some programming tasks to try using the LMC

  1. Write a program that will prompt for 2 numbers, subtract the first from the second and output the answer, then subtract the second from the first and output the answer.
  2. Write a program to output the numbers 1 to 10 in ascending order.
  3. Write a program to output the numbers 1 to 10 in descending order.
  4. Write a program to input a number then count up to that number in steps of 2, outputting the sequence.
  5. Write a program that will input two numbers and multiply them.
  6. Extend the program above that it will let the user repeatedly input and multiply pairs of numbers, only stopping if a zero is entered.
  7. Extend the program above so it will let the user enter either or both numbers as negative values.
  8. Write a program that will prompt for 2 numbers and check if they are the same. If they are then the program should output the number 1. If they are not then the program should output the number 0.
  9. Write a program that will input an number, then output the square of the number.
  10. Modify the squares program above so if an input above 31 is entered then it will output a zero.
  11. Modify the squares program above so it will also square negative number inputs.
  12. Write a program to input 3 numbers and then output the highest.
  13. Write a program to input 3 numbers and then output the highest AND the lowest.
  14. Write a program to divide one number by another.
  15. Modify the previous program so it generates a decimal answer rather than a remainder.
    A simple way to do this is to multiply the remainder by 10 and then divide this number by the original divisor. If this is repeated it will generate the result of the division to unlimited decimal places. This can be done in 42 lines of LMC code.
  16. Write a program to input a number and then outputs:
    a) the number
    b) the integer square root
    c) the remainder.
    A simple way to calculate an integer square root is to count how many times increasing odd numbers can be subtracted from the starting value.

32-1=31 -> 31-3=28 -> 28-5=23 -> 23-7=16 -> 16-9=7 -> 7-11<0
1 2 3 4 5 -> SQR(32) = 5 remainder 7

For example:
SQR(32)

  • Write a program to calculate PI to 6 decimal places (3.141592).
    This can be done by ‘dividing’ 355 by 113 to get the integer 3. The remainder is ‘multiplied’ by 10 and then ‘divided’ again by 113 to get the first decimal place. This is then repeated 6 times. 355/113 is used as there is no “better approximation” among all fractions (P/Q) with denominators less than 30,000.
  • Factors to consider when writing programs in assembly language/machine code using the LMC

    • How easy is it to follow programs with many conditional instructions or iteration loops?
    • What are the issues when trying to create program structures such as subroutines, for/next loops, while/endwhile loops, repeat/until loops or if/then/else/endif decisions?
    • Is the fact that there are only 100 address locations in RAM to store both the program instructions and the data an issue?
    • Does it matter that data can normally only be placed in the memory address of the DAT statement?
    • Does that fact that instructions and data are both stored together in RAM cause any issues when writing a program?
    • Can the equivalent of an array be created to store and process a series of values as a program runs?
    • Is it easy to carry out non-integer arithmetic?
    • What if you needed higher level functions such as square-roots, trigonometry or needed more complex calculations that would require brackets and the use of AND/OR/NOT?
    • What if you wanted to incorporate text or basic graphics in your program?

    Demonstration programs using the LMC

    Bubble Sort

    inputLoop INP
    BRZ sortLoop
    store DAT 380
    LDA store
    ADD increment
    STA store
    LDA listSize
    ADD increment
    STA listSize
    BRA inputLoop
    sortLoop LDA listSize
    SUB increment
    STA loopCount
    LDA zero
    STA isChange
    load1 DAT 580
    STA buffA
    load2 DAT 581
    STA buffB
    cmp SUB buffA
    BRP nextItem
    swap LDA buffB
    store1 DAT 380
    LDA buffA
    store2 DAT 381
    LDA increment
    STA isChange
    nextItem LDA store1
    ADD increment
    STA store1
    ADD increment
    STA store2
    LDA load1
    ADD increment
    STA load1
    ADD increment
    STA load2
    LDA loopCount
    SUB increment
    STA loopCount
    BRZ isFinished
    BRA load1
    isFinished LDA isChange
    BRZ outputList
    resetLoop LDA lda1
    STA load1
    ADD increment
    STA load2
    LDA sta1
    STA store1
    ADD increment
    STA store2
    BRA sortLoop
    outputList DAT 580
    OUT
    LDA outputList
    ADD increment
    STA outputList
    LDA listSize
    SUB increment
    STA listSize
    BRZ end
    BRA outputList
    end HLT
    zero DAT 0
    buffA DAT 0
    buffB DAT 0
    isChange DAT 0
    increment DAT 1
    listSize DAT 0
    loopCount DAT 0
    sta1 DAT 380
    lda1 DAT 580

    A sorting program, input values are stored from memory address 80 onwards (therefore a maximum of 20 numbers can be sorted). An input of 0 starts the sort.

    Trinum

    start INP
    STA value
    LDA zero
    STA trinum
    STA n
    loop LDA trinum
    SUB value
    BRP endLoop
    LDA n
    ADD one
    STA n
    ADD trinum
    STA trinum
    BRA loop
    endLoop LDA value
    SUB trinum
    BRZ equal
    LDA zero
    OUT
    BRA done
    equal LDA n
    OUT
    done BRA start
    value DAT
    trinum DAT
    n DAT
    zero DAT 0
    one DAT 1

    This program inputs a value (greater or equal to zero) and outputs which triangular number it is, or 0 if it is not a triangular number. For example, if the input is 15 the output will be 5 (15 is the 5th triangular number) and if the input is 7 the output will be 0 (7 is not a triangular number).

    The triangular numbers are as follows:
    1 = 1
    3 = 1 + 2
    6 = 1 + 2 + 3
    10 = 1 + 2 + 3 + 4
    15 = 1 + 2 + 3 + 4 + 5
    21 = 1 + 2 + 3 + 4 + 5 + 6
    etc.


    Number Store

    writeLoop INP
    BRZ readLoop
    writeStart DAT 350
    LDA writeStart
    ADD one
    STA writeStart
    LDA count
    ADD one
    STA count
    BRA writeLoop
    readLoop LDA count
    SUB one
    STA count
    BRZ done
    readStart DAT 550
    OUT
    LDA readStart
    ADD one
    STA readStart
    BRA readLoop
    done HLT
    count DAT 1
    one DAT 1

    This program illustrates the LMC equivalent of an array, storing each successive INPUT in successive memory locations and counting (the equivalent of the array index) how many numbers are input. The numbers are then OUTPUT in the same order they were entered when a zero is entered.

    The program has to alter some instructions as it runs. It does this by treating them as data (they are loaded, altered and saved) and in this program the ‘data’ values 350 and 550 are treated as STA (store) and LDA (load) instructions respectively by the LMC. This ‘data’ is altered as the program runs by adding a 1 to it so that it stores INPUT values in memory locations 50 onwards.


    Memory Overwrite

    BRA writeLoop
    s1 DAT
    s2 DAT
    s3 DAT
    s4 DAT
    s5 DAT
    s6 DAT
    s7 DAT
    s8 DAT
    s9 DAT
    writeLoop INP
    BRZ readLoop
    writeStart DAT 300
    LDA writeStart
    ADD one
    STA writeStart
    LDA count
    ADD one
    STA count
    BRA writeLoop
    readLoop LDA count
    SUB one
    STA count
    BRZ done
    readStart DAT 500
    OUT
    LDA readStart
    ADD one
    STA readStart
    BRA readLoop
    done HLT
    count DAT 1
    one DAT 1

    This program illustrates one of the issues with memory being used for both instructions and data. As the program runs, numbers are INPUT and stored in memory locations 0 onwards. When memory location 10 is reached the instructions in the main program loop start to be overwritten with data, causing the program to stop running correctly as the LMC tries to interpret the data as an instruction.