Back

Assembly languages and the Little Man Computer

Introduction
Some programming tasks require a programmer to program in a way that reflects the CPU design. The programmer may need, for example, to directly manipulate memory addresses or the CPU's registers. This is often true when a device driver for a piece of hardware is being written or when a translator is being written for a high level language. It would be appropriate in these cases to use a language that has instructions designed to easily carry out these tasks. High-level languages generally would not be the first choice, because their focus is more on solving application-based problems. The first choice would be assembly languages. These types of languages have instruction sets that reflect the way the CPU carries out its instructions, including instructions that allow you to manipulate a CPU's registers. Their instructions are very close to machine code itself. These languages use mnemonics, which are reasonably easily remembered codes for instructions. Examples include:

    • DIV 18 ---- Divide the contents of the accumulator by 18 and store the result in the accumulator.
    • LDA (3000) ---- Get the contents of address 3000 and move them to the accumulator.
    • SUB (5000) ---- Get the contents of address 5000 and subtract them from the accumulator. Store the result in the accumulator.
    • MOV B @100 ---- Get an address held in address 100. Go to that address and get the contents. Move them into accumulator B.

Note that decimal numbers are used in my examples throughout this section for simplification. Using hex might be an easier option! Can you think why? Note that in the above examples, each instruction has an instruction part and an address part to it. For example, in the instruction LDA (3000), the LDA is the instruction part of the instruction and the 3000 is the address part of the instruction. The address part refers to an address where the CPU needs to look in RAM to find some data. This is a very common format for assembler instructions (although a few instructions differ from this format).

    • The instruction part of an assembler instruction is usually known as the operation code, or opcode for short.
    • The address part of the instruction is usually known as the operand.

We can represent this general format of most assembler instructions like this:

<OPCODE><OPERAND>

The fetch-decode-execute-reset cycle (FDER cycle)
You want to run a program that you have on your hard disk. You double-click on it in your file manager. The loader program (part of the operating system) goes to the hard disk and copies it to a suitable place in the IAS. It adjusts any memory references in the program as appropriate and then loads the address of the first instruction of the program into the Program Counter (PC). It then signals to the CPU that it has done this. The CPU wants to run the program and gives control to the control unit. The control unit fetches the first instruction from the IAS. It then decodes it and executes it. Once executed, the cycle is reset and the control unit fetches, decodes and executes the next instruction in the program, then resets the cycle again. This process is repeated until the whole program has been ‘run’. At all stages in the FDER instruction, the CPU will need to use the registers. These are discussed in detail below.

The fetch part of the cycle
Every program has a start address. The start address is placed in the Program Counter (PC). At the start of execution of the program, the Control Unit looks at the memory address in the PC. It goes to that address in memory and copies the bit pattern that it finds there to the Memory Data Register (MDR), where it is then copied to the Current Instruction Register (CIR). While it is doing this, the PC is automatically incremented, so it is pointing to the memory address of the next instruction. The following describes what happens in the fetch part of the FDER cycle.

Note that the registers are used in this way for the fetch part of EVERY instruction, regardless of what the instruction actually is.

The decode/execute/reset part of the cycle
Once the instruction has been fetched, it needs to be decoded and executed. What happens next depends upon the actual instruction. The contents of the CIR are decoded.

IF the instruction turns out to be a CONDITIONAL JUMP instruction, THEN

    • The Status Register is examined.
    • If a jump is required, then the operand associated with the jump instruction is copied to the PC and a reset signal is generated to end the current FDER cycle. If it is not required then the FDER cycle is simply reset.

ELSE IF the instruction is an UNCONDITIONAL JUMP, THEN

    • Copy the operand associated with the unconditional jump to the PC.
    • Reset the cycle.

ELSE

    • Execute the instruction using the registers.
    • Reset the cycle by going back to the beginning of the fetch-decode-execute-reset cycle.

ENDIF

For example, the control unit fetched an instruction using the registers. It was decoded by the instruction decoder and found to be JMZ 4. JMZ means ‘jump to the address given in the operand if the result of the last instruction produced a negative result’. The operator is JMZ and the operand is 4.  

    • Because this is a ‘conditional jump’ instruction, the Status Register is examined.
    • The status register holds information about the last instruction that was done. It can be thought of as a byte, with 8 bits, each bit indicating a status – one bit would indicate if the last instruction done produced a carry, or an underflow, or an overflow, or if the result of the last instruction produced a negative number.
    • The bit associated with negative numbers is examined.
    • Assuming that the last instruction did indeed produce a negative result, this bit is found to be set.
    • The control unit therefore loads the operand associated with JMZ into the PC (in other words 4 is loaded into the PC) and the current FDE cycle ends.
    • This FDE cycle has now finished so the next instruction must be done. The address of the next instruction to do is held in the PC.
    • The control unit goes to the address held in the PC and fetches it – it goes to memory address 4 and gets the instruction it finds there.
    • The program has successfully branched off to a different part of the program (beginning at address 4) than it would have done. A jump to a subroutine has been achieved!

Executing an instruction
So far, we haven’t discussed how instructions are actually executed. This is achieved using the registers, just as the fetching of instructions is achieved using the registers. Study the following example. Do notice how the special register known as the Accumulator is used! It is central to every single operation. You do any actual mathematical or logical operations in the Accumulator. That means that before you can work on any data, you must put it into the Accumulator first. This is straightforward. Simply put the operand of the instruction on the MAR and then move the contents of the MDR to the Accumulator. To store the Accumulator’s contents, simply put the address where you want to store the contents on the MAR and then move the Accumulator to the MDR. Also note ADD (x) instructions usually take the form of ‘ADD the contents of a location given by the operand x to the contents of the Accumulator and store the result in the Accumulator’. SUB (x) means ‘subtract the contents of the location given by x from whatever is in the Accumulator and store the result in the Accumulator’.
If you wanted to add two numbers together, held in locations 2000 and 3000 and store the result in 4000.

The instructions might be:

LOAD (2000)         //This loads the contents of memory location 2000 into the accumulator.
ADD (3000)           //This adds the contents of location 3000 to the accumulator, storing the result in the accumulator.
STORE (4000)      //This instruction takes whatever is in the accumulator and stores it in location 4000.  

The use of the registers can be summarised as follows:

  • The PC or Program Counter. This register holds the address of the next instruction in the Fetch-Decode-Execute cycle.
  • The MAR or Memory Address Register. The contents of the PC are loaded into the MAR. This allows the PC to be incremented.
  • The MDR or Memory Data Register. This register holds the bit pattern held in the address pointed to by the address in the MAR.
  • The CIR or Current Instruction Register. This register holds a copy of the bit pattern in the MDR, thus freeing up the MDR.
  • The Accumulator. All logical and arithmetic operations take place in the accumulator. Sometimes there is more than one accumulator and these might be referred to as accumulator A, accumulator B etc.
  • The Interrupt Register. This holds information about what interrupts have happened. It will be checked after each Fetch-Decode-Execute cycle.
  • The Status Register. This register gets updated after every ALU operation. It holds information about the result of the last operation that was carried out. It will tell you whether the last operation produced a carry bit, whether the result was zero, or negative, or there was an underflow, or an overflow, for example.
  • The Input Register. This register is used to transfer information from an input device into the CPU.
  • The Output Register. This register is used to transfer information from the CPU to an output device.

Little Man Computer
There are a number of ways to help yourself really understand how registers are used to fetch, decode and execute the instructions in a program. One way is to spend a few hours using the Little Man Computer simulator.

Here is an excellent description, some simple notes to get you started and some links where you can go to set it up on your computer:

https://community.dur.ac.uk/m.j.r.bordewich/LMC.html

You can also go here:

http://www.yorku.ca/sychen/research/LMC/

and use the online simulator.

Spend a few moments looking through the set of instructions available to you using the Little Man Computer. You can find the complete instruction set here:

http://www.yorku.ca/sychen/research/LMC/LMCInstructions.html

Once you have got access to the Little Man Computer and read about some of the instructions you can use, it's time to program in Assembly. Simply open up each example here:

http://www.yorku.ca/sychen/research/LMC/

Read the description and then follow the instructions.

YouTube
If you start to get confused or need a bit more help, you should go to YouTube and watch some of the many short videos available about the Lttle Man Computer:

https://www.youtube.com/results?search_query=Little+Man+Computer

Back