咱们来看看MSP430 Microcontroller Basics一书Page 154所描述的:
5.6.3 Is the MSP430 a RISC—and Should It Be?
TI describes the MSP430 as having a RISC 16-bit CPU although it is sometimes more
cautious and merely calls it RISC-like. A discussion of the classification alone would be
sterile but it is interesting to see what features of a RISC were adopted by the designers of
the MSP430, which they rejected, and why. Furber [36] has a fascinating and accessible
discussion of RISC and CISC processors focused on the ARM family, which is usually
considered to be one of the first RISC processors although it does not fit the usual
definition fully. Four main features characterize a RISC:
Small set of general-purpose instructions: In contrast to the large number of
instructions with different formats in a CISC (over 250 in the Freescale HCS08, for
instance).
Large bank of general-purpose registers: Used for both data and addresses, in
contrast to the small number of specialized registers in a CISC (the HCS08 has a single
accumulator for data and a separate index register for addresses).
Load–store architecture: In which instructions that process data use only the registers
in the CPU and cannot operate on memory directly; separate instructions load data from
memory into the CPU and store the result back into memory.
Single-cycle execution: Unlike the variable number of cycles required by a CISC.
The MSP430 displays the first two features but not the last two, and it is worth considering
why these were rejected. The basic reason is that small microcontrollers spend much of
their time performing simple operations on registers in the main address space. These
often reconfigure a peripheral. For example, suppose that we wish to stop Timer_A, which
requires bits MC0 and MC1 of TACTL to be cleared. It can be done in a single instruction
in the MSP430:
bic.w #MC0|MC1 ,& TACTL ; stop timer [3 words , 5 cycles]
This requires three words to hold the instruction itself, the immediate data for the source,
and the absolute address for the destination. It takes five cycles to fetch the instruction,
fetch the immediate value, fetch the address of the destination, fetch the original value of
the destination, and write back the modified value of the destination. How would this be
done in a “pure” RISC processor? Here is a possibility, making minimal changes from the
MSP430:
load.w #TACTL ,R4 ; load address of TACTL [2w, 2c]
load.w @R4 ,R5 ; load value of TACTL [1w, 2c]
load.w #MC0|MC1 ,R6 ; load immediate operand [2w, 2c]
bic.w R6 ,R5 ; perform operation [1w, 1c]
store.w R5 ,@R4 ; store result for TACTL [1w, 2c]
I assume that all addresses must reside within the CPU, so that load.w &TACTL,R5
is not permitted; instead we must first store the address as an immediate value into a
register and use indirect addressing. As usual the number of cycles is set by the access to
memory. The bad news is that this requires five instructions, seven words, and nine cycles,
roughly twice the storage and time of the MSP430. This shows immediately why RISC
processors have a reputation for poor code density. The RISC also is slower unless the
processor is simple enough that the speed of the clock could be raised, but in practice this
is probably limited by the speed of the memory rather than the CPU. It may be possible to
embed a byte of immediate data in the instruction, which would assist operations on
peripheral registers with byte access.
Another benefit of the MSP430’s single instruction is that it cannot be broken by an
interrupt—instructions are always completed before an interrupt is taken. The jargon is
that it is atomic. In contrast, an interrupt could occur between the five instructions of the
RISC processor. The programmer may need to guard against potential side effects; see the
section “Issues Associated with Interrupts” on page 196.
Of course it is easy to find examples where the RISC performs better. The inner loop in
MyStrCpy could be rewritten like this:
CopyLoop:
load.b @R14+,R15 ; [1 word , 2 cycles]
store.b R15 ,@R12+ ; [1 word , 2 cycles]
jnz CopyLoop ; [1 word , 2 cycles]
This requires only half the storage and cycles of the version in Listing 5.1. The main saving
comes from autoincrement addressing in the store operation, which is not permitted for a
destination in the MSP430. It is likely that a RISC would offer further addressing modes,
such as predecrement to complement postincrement, and that these could be used with a
base address to provide further indexed modes. Small microcontrollers usually spend more
time writing to peripheral registers than copying or manipulating blocks of data, so the first
example is more relevant. Therefore the designers of the MSP430 chose not to adopt a
strict load–store architecture but to allow operations on main memory instead. |