L09 [Assembly Programming] - Skyline-9/CS2110-Notes GitHub Wiki

L09 [Assembly Programming]

What can you do with ADD, AND and NOT?

Enough to be Turing Complete!

  • Add
  • And
  • Not
  • Subtract
  • Or
  • Clear a register
  • Copy from one register to another
  • Increment a register by n, -16 <= n <= 15

How do you copy one register from another?

  • Example: you want to copy R5 to R1

Do we load R5 into R1? NO! Load doesn't copy a register from a register

Subtraction

;SUB R1, R2, R3 ;instruction does not exist
; how to subtract

NOT R3, R3 ;flip the bits of R3
ADD R3, R3, #1 ;add 1 to R3 ;now R3 is -R3
ADD R1, R2, R3

Or

;OR R1, R2, R3 ;does not exist: R1=R2 | R3
; how to do OR ;use DeMorgan’s Law
NOT R2, R2 ;R2 = ~R2
NOT R3, R3 ;R3 = ~R3
AND R1, R2, R3  ;R1 = ~R2 & ~R3
NOT R1, R1 ;R1 = ~(~R2 & ~R3)

Clear

;CLR R1 ;e.g. set R1 = 0
AND R1, R1, #0 ;R1 = R1 & 0
;anything and zero is zero

Move

;MOV R1, R2 ;e.g. R1 = R2
ADD R1, R2, #0 ;R1 = R2+0; R1 = R2

What can we do with a BR?

  • If then else
  • For
  • While
  • Else
  • Do while
  • Conditional Branch
  • Unconditional Branch (BRNZP or BR)
    • Ex: end of a while loop
  • Never branch (NOP)

What can we do with a JMP?

  • What can we do with a JMP?
  • GOTO
  • Branch very long distances
  • Rarely use JMP

How do we do IF using a BR (branch)?

  • First do an operation to set the condition codes
  • Then BR with the appropriate combination of NZP conditions in the instruction
  • Every comparison in assembly is a comparison with 0 (e.g. A < B becomes A - B < 0)

Attendance Quiz Solutions [9/30/2021

  1. What does this assembly directive do? C .blkw 20

Sets C to the current address and reserves 20 words of memory starting at C

  1. The assembly symbol table is

Created during the first pass of assembly

Recitation Notes

LC-3 Components (a quick review!)

What does the IR hold?

  • The value of the current instruction

How do you execute an instruction?

Stages

  1. Fetch
  2. Decode
  3. Execute

What happens you do fetch?

  • Use PC value (address of next instruction) to read the next instruction from memory
  • Load this value into the IR so that it can be decoded and executed later
  • Increment the value of PC

More specifically, you would

  • Set PCMUX to +1
  • Turn on LD.PC
  • Turn on gatePC
  • Trn on LD.MAR to read into MAR
  • The +1 can happen in any of the FETCH cycles

Sample question: How would you increment the PC during the FETCH cycle?

  1. Turn on LD.PC and set PCMUX to +1

The macrostates are like Fetch, and the individual clock cycles are called microstates

What happens during decode?

  • Now that the IR contains the instruction, the FSM can read the opcode
  • If the instruction is BR (branch), the FSM will also check the condition codes to ensure that the branching condition is met
  • The FSM will change to a specific state depending on the opcode. This takes a clock cycle in the LC-3, but some computers can combine DECODE with the last cycle of FETCH.

Other Notes About Tracing

What does LD do?

Specifically, LD has to take some address, take the value at that address, and then put that value into the register specified.

Effective address = PC* + PCOffset9 where PC* = PC + 1 and PCOffset9 is SEXT(IR[8:0])

What does LDI do?

The first address for LDI is the same for LDI as LD, but you take the value you first read and then push it back into the MAR

What does LDR do?

Effective address = Base Register + offset6

What does LEA do?

LEA = load effective address

  • Only takes one clock cycle
  • Calculate effective address and put it straight into Register because you don't have to read memory

For all the ones where you need to update the register, you need to set LD.CC except for LEA

  • This allows you to do branching instructions

What stores the list of upcoming instructions?

  • Memory

What calculates the list of effective addresses?

  • The entire left half of the LC-3 (see diagram)

How many LC-3 instructions set the condition codes?

  • Just count the ones with DR (both the ADDs count as one, same for the similar ones)
  • 6 instructions set the condition codes

What happens when there is a branch instruction?

The branch instruction has these NZP bits (which match up with the NZP in our condition code)

Example, if we have if x > 0

  • We just check if x is positive

We can reduce many problems to just that – ex: if x > y

  • Check x - y > 0

First, NZP are compared with the condition codes. Now, we have to jump somewhere. Where to jump? We calculate the effective address using PCOffset9

Fun fact: BRNZP is equivalent to BR.

What happens if we have all 0's?

You get what is called NOP (or no op). Basically, this tells the LC-3 to do nothing for a cycle.

We get to use reference sheet on our demos! ^_^

Assembly

Labels

  • Some LC- 3 instructions use the PC-relative addressing mode for operands
  • These accept labels as a second parameter, allowing programmers to load from labeled memory addresses
  • Labels are not stored anywhere in memory. Instead, the assembler calculates the right numerical offset to get to the desired label
  • To calculate the offset yourself, find the difference between the memory address of the label and the incremented address of the instruction (which will be the value stored in the PC when it executes)

When you do branch, you could count the lines of code and branch that way, but that's dumb. Instead, we use labels.

Friendly reminder: these addresses are in hex, so x10 is actually 16.

LC-3 Assembly “Pseudo-Ops”

.orig

  • Stands for "Origin"
  • Tells assembler to put block of code at desired address
.orig x3000
  • You can have multiple origs

.end

  • Denotes the end of block, closing tag for orig

.fill

  • Puts value in memory location

.blkw

  • Allocates memory for specified label

.stringz

  • Assembler will put a string of characters in memory followed by ‘\0’
  • Will allocate length of string + 1 for the null character

Random Notes

  • Why did we learn DeMorgan's Law?
    • The LC-3 actually does not have an OR operation!
    • We have to negate it with DeMorgan's Law everytime

Tips for writing assembly

Don't try writing assembly natively from scratch! Instead, write pseudo-code like

short Mem[65536];
int S = 0;
int M = x3100;
int C = 12;

while (C > 0) {
    S = S + Mem[M];
    C = C - 1;
    M = M + 1;
}

and then translate line by line into assembly. This way, we might not have the most efficient program, but we can have what's important – having correct code!