CS 273 Course Review
Course Review
Reading: Textbook, pp 11-23\
Bus-Based Architecture
- Address/Data bus between CPU and memory and I/O
- Our HC11 happens to have on-chip memory, but the idea is the same
- The HC11 has a 16 bit address bus, and an 8-bit data bus
ISA -- Instruction Set Architecture
Registers
Instructions
Condition Codes
Address space
Addressing modes
I/O design
- separate address space (Intel x86) or memory-mapped I/O (HC11)
Control Registers
Interrupts
Timing?
Timing
HC11 has a very simple model
- a fixed number of cycles per instruction
Compare memory speeds with today's CPU's
Idea of a cache
- a small amount of very fast memory -- keeps recently used values
- completely automatic -- CPU does not know about it
- a cache is not part of an ISA
- an instruction accessing memory will take a different number of cycles, depending on whether the value is in cache or not
Idea of a pipeline
- compilers sometimes know about pipelines
Addressing Modes -- Or where the instruction gets its data
Inherent -- register name is in instruction
Immediate -- the value to be used follows the instruction
- in essence, the PC contains the address of the data
Extended -- a 16 bit address is given
Direct -- an 8-bit address is given (upper byte is assumed to be $00)
- direct is redundant (not needed), but is faster and smaller.
- some CPU's have an addressing mode called segmented -- it is like the HC11 direct, but the upper part of the address is not just a constant (like $00), it can be defined and set. The Intel x86 CPU's have this.
Indexed -- an 8-bit offset (unsigned) is given to be added to a 16 bit index register (X or Y)
Relative -- an 8-bit 2C value is added to the current PC (for branching)
- enables relocatable machine code -- the branch destination is not a fixed address
Stack -- the SP register holds the address (for push/pop(pull) instructions)
Condition Codes
A set of bits that save the properties that hold from the previous instruction's computation
- C -- was there a carry out of the register, or needed for a subtraction?
- V -- was there a 2C overflow (value to big)?
- Z -- was the result exactly zero?
- N -- was the result negative (for 2C)?
Condition codes are used by the branch instructions
- Remember, a compare (or test) instruction is just a subtraction
Upper 4 bits of CCR:
- I -- are interrupts enabled are not? (the CLI instruction)
- H -- half-carry from bit 3 (used for doing some odd arithmetic)
- X -- are non-maskable interrupts enabled? (?)
- S -- stop-disable
- these bits (except for H) are more control oriented rather than condition oriented
Assembly Language Programming
The lowest level of programming is not assembly language, but writing machine code directly!
- to write machine code, you need to figure out the opcodes and addresses yourself
- people used to do this -- and even entered each bit with an individual switch by hand!
Assembly language associates a mnemonic name with each instruction
- actually, with each class of instructions, since opcodes change based on addressing modes
- for example, all LSL opcodes use the same name, LSL, but their opcodes are different
An assembler automatically translates the instruction names into machine code
- it also lets you use constants, symbols, labels, binary, hex, decimal, etc.
Control Structures
If-then-else
<some kind of test that sets the CCR>
While loop
wloop <some kind of test that sets the CCR>
Do-while loop
wloop <loop body>
For loop (counting)
<set the counter to initial value>
Switch
- We didn't cover, but it is essentially a n-way if statement.
Stacks and Procedures
All CPUs have direct support for a stack
- the HC11 has an SP register
- Intel x86 cpus have an SP and a BP register (BP==base pointer)
- the stack is just an area of memory that is used as a stack data structure
- most stacks grow towards decreasing memory addresses (the HC11 stack does)
The stack is mainly used to support nested procedure (function) calls
A procedure call is accomplished with two special instructions
- a special jump instruction JSR (jump to subroutine), which jumps to the label beginning the procedure, but also pushes the return address onto the stack
- the return address is the address of the instruction immediately sequentially after the JSR
- the RTS (return from subroutine) instruction is the last instruction in the procedure. It pops the return address off the stack and into the PC, which causes the execution to jump back to the caller, and execute the next instruction in the caller's code
Each procedure call results in an activation record on the stack
- the activation record at the least holds the return address to return back to the point of the call
- it may also hold arguments (actual parameters), local variables, and saved registers
The caller is responsible for pushing arguments onto the stack, and pulling them off (or simply reclaiming the space they took)
In C, arguments are pushed on in reverse order, so that the first argument is always in the same place regardless of the number of arguments
- this allows functions like printf() to take a variable number of arguments
The two main styles of parameter passing are call-by-value and call-by-reference
In call-by-value, the value of the argument is pushed onto the stack
- the procedure can change the value of the argument, but it is only changed on the stack (like a local variable) and thus does not affect anything outside of the procedure call
In call-by-reference, the address of a variable is pushed onto the stack
- the procedure can assign a value to this address, and thus can change the caller's variable that was used as the argument
Arrays in C are inherently passed as call-by-reference.
Integer-sized return values from functions that return a value are generally left in an agreed-upon register
- Other-sized return values are often left on the stack (we didn't study this)
There are generally some set of agreed-upon registers that should not be corrupted by a procedure call
- In other words, the caller should be able to expect the same values in them after the procedure call as were in them before
- If the procedure uses these registers, it must first save their original values on the stack, and then restore them before it returns
A recursive function is simply one that calls itself. Multiple activation records accumulate on the stack as the function recurses.
Interrupts
Miniboard I/O
Floating Point
Boolean Algebra and Digital Circuits