- Traps and interrupts.
- Real-World ISAs
- Much more arithmetic.
- Multiply and divide instructions.
- Floating point instructions.
- Sometimes BCD support.
- Logical instructions.
- Bit-wise and, or, xor, not.
- Shifts and rotates.
- Control transfer.
- MARIE-style skips are not common now.
- Conditional branches.
- Branch performs the comparison, and branches if true.
- Compare sets flags, and branch tests flags (Pentium-style).
- Variable memory units.
- Byte-addressable memory.
- Register size of four bytes or more.
- Instructions to store/fetch in 1, 2, 4, maybe 8 byte units.
- Longer units have multiple addresses
- Little-endian: Low-order byte in lowest address.
- Big-endian: High-order byte in lowest address.
- Pentium uses little-endian.
- Multiple registers.
Pentium (32-bit) EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP,
plus status word
MIPS $0-$31.
ARM R0-R15, plus status word.
- Arithmetic is often, or only, between registers.
- Some registers have special purpose, either in the
architecture, or by convention.
- A system stack.
- One register is the stack pointer. It holds an address which is
the top of the stack.
- Push and pop by moving the stack.
- Function calling generally uses the stack.
- Immediate operands. Most machines have an instruction to load
a constant into a register, usually of limited size.
- Addressing modes.
- Relative: address = register + offset.
- Widely (universally?) available.
- Offset of zero allows indirect addressing.
- Often used with the stack pointer, to access data relative to the
current stack top.
- Direct addressing (like Marie) is rarely used.
- Sometimes indirect addressing through memory, like FetchI has been
provided, but not usually on current architectures.
- Instruction format.
- Older designs (notably Pentium) have instructions of differing size.
(Current architectures have instructions all the same size.)
- Format must be able to specify at least two arguments.
- Op codes may be variable sized.
- Book describes this under “Expanding Opcodes”.
- For instance:
- First 15 op codes are four bits 0000–1110.
- Next 15 are eight bits: 11110000–11111110
- And 8 more at eleven bits: 11111111000–11111111111.
- Can use the short codes for instructions which are common or
have longer arguments.
- Stack architectures
- Not to be confused with a system stack.
- Operations are applied to the stacktop instead of registers.
- Not common.
- Pipelines
- Speed up the CPU by working on multiple instructions at the same time.
- Most like an
assembly line..
- The assembly line is made of large registers. The instructions,
along with needed partial results, pass from one to the next.
- Results are saved at the end; partial results may be safely discarded.
- Data dependence is a problem
- An instruction uses a value produced by a previous one.
- Pipeline must wait, or values must be copied backwards.
- Conditional branches are a problem
- Don't know what the next instruction is.
- Approaches.
- Just stall the pipeline: Don't fetch instructions past the branch
until the result is known.
- Static branch prediction
- Always assume instruction does not branch.
- When you find out that it does, discard following partial results.
- Dynamic branch prediction
- A small cache keeps track of recent branch results.
- One-bit: Retain last branch result and presume next will do
the same.
- Two-bit: Retain last two results. Make the same predition
until its wrong twice.
twice.
- Fetch both instructions, one for branch and one for not
- Discard the wrong one as soon as you know.
- Generally requires duplicating many components so you can
do both branches at once.
- Delayed branch
- The ISA semantics specify that the instruction after the branch
is executed unconditionally, and any branch takes
effect after that.
- Depends on a smart compiler to find something to do during the
delay slot.
- If there's nothing useful to do, code a no-op.
- Super-scalar: Multiple pipelines.
- Instructions must be dispatched in groups.
- Dependencies within the group are a problem.
- Hardware manages the dependencies.
- They are just errors; compiler must arrange the instructions.
- MIPS
- Each instruction is 32 bits, in one of three formats.
R-Format (add)
op
r1
r2
rdest
shamt
func
I-Format (load, store)
op
rb
rsd
offset
I-Format (branch)
op
r1
r2
offset
The op and func codes are each 6 bits,
the register numbers are 5, the offset is 16, and
the jump target is 26.
- The R-format uses a form of what the book calls “Expanding
Opcodes.” The “op” for all math operations is the same,
distinguished by the “func” code.
- Register numbers are 0-31, but 0 is a constant “register” which
always contains zero.
- Assember programs can designate a register with either its number or
a standard symbolic name.
- Symbolic names reflect conventional use, such as $sp for
stack pointer.
- MIPS Example (runs on the SPIM simulator).
- Pentium
- EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP are the main program-accessible
registers.
- Instructions have a complex, variable length code,
described
in some detail here.
- Briefly, each instruction has up to six parts, all but the op code
optional.
- Prefixes, 0–4 bytes. Various behavior modifiers.
- Op code, 1 or 2 bytes.
- ModR/M, specifies what type of arguments are used (registers,
memory references, type of memory reference computation, or
immediate). It also contains one or
two argument register numbers, as needed.
- SIB, if the ModR/M specifies it should be present, describes
an argument address computation using two registers, one
shifted by a power of two. It is one byte long.
- Displacement, 1, 2 or 4 bytes. A constant added to the computation
specified by the SIB. The ModR/M specifies if this needs to
be present.
- Immediate value, 1, 2 or 4 bytes. Present when one of the
arguments is a constant.
- Designed to minimize the memory space needed to store a program. Folks
don't worry so much about this anymore.
- Don't need to know about the JVM discussion in the text.