2.5: Designing an Assembly Language
- Page ID
- 27242
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)When designing an assembly language, a language to manipulate a CPU, there are 3 major concerns:
- Transferring data from main memory to memory internal to the CPU (registers or operand stack).
- The set of operations that can be performed by the ALU on the data, for example
add
,subtract
, and,shift
, etcetera. - A way to provide program control, for example to implement branch (if) and looping (for or while) type structures in a program. Normally control structure will be provided by a branch operation.
These three major concerns, and how they are addressed in the assembly language, will be discussed in the next sections. The last section of this chapter will give some programs that will illustrate how a program will be written in this assembly language.
2.5.1 Transferring data from main memory to internal CPU memory
The amount of memory directly accessible to a programmer on the CPU (e.g. registers) is very limited. In the case of the one-address architecture, only one memory slot, the $ac
, is directly useable by a programmer. Therefore programs need to rely on main memory to store program instructions and data.
To transfer items from data memory to the $ac the instructions add, sub, and stor are used.
For the add
and sub
instructions, the second operand of the instruction is the label or memory address of the value to retrieved from memory and sent to the ALU. So for example, to load a value into the $ac from a memory location labelled A the following code would be used.
clac add A
Note that the $ac
should always be set to 0 (using the clac
) before loading a value into the $ac, or the value stored in the $ac
will be the result of adding the value at memory location A with the current value in the $ac
.
For the stor
instruction, the second operand is the label or memory address at which to stor
the value from the $ac
. For example, to store the value in the $ac
to memory at the address in label B, the following code would be used.
stor B
2.5.2 Set of valid ALU operations
The next consideration is the set of operations which the ALU can perform on the input data. This list depends on the complexity of the ALU. The ALU in this computer is very simple, and so will only support the operations add and sub.
2.5.3 Program Control (Branching)
To do any useful program, if and loop constructs must be supported. In the implemented one- address CPU this is accomplished by the Branch-if-equal-zero (beqz
) operation. For this operation, if the $ac
is 0, the program will branch to the text memory address that is contained in the branch statement. This address can be either a label representing the address, or the numeric value of the branch address. So in the following instruction, the program will branch to the address of label EndLoop if the value in the $ac
is 0
.
beqz EndLoop
An unconditional branch statement is often used, but can be simulated by first setting the $ac
to 0
before the branch statement. The following instruction implements an unconditional branch.
clac beqz StartLoop
2.5.4 Assembler Instructions
Based on the criteria of the preceding section, A minimum set of assembler instructions is defined to create useful programs. These instructions are sufficient to create useful programs, and several examples will be shown at the end of this chapter.
- Either a label or the actual address of the value can be used in this instruction. Thus if the label A refers to the dm address of 5, the following two instructions are the same.
add A add 5
addi
immediate
- Add the immediate value in this instruction to the$ac
. The immediate value is an 8-bit integer value between -128...127$ac <- $ac + immediate
An example of an addi instruction which adds 15 to the value in the $ac follows.
addi 15
beqz [label/address]
– Thebeqz
instruction changes the value in the Program Counter ($pc
) to the text memory address in the instruction if the value in the$ac
is0
. In this CPU, the$pc
always specifies the next instruction to execute, so this has the effect of changing the next instruction to execute to the address in the instruction. This is called a program branch, or simply branch.$pc <- address IF $ac is 0
An example of the
beqz
instruction that branches to address 16 if the$ac
is0
follows:beqz 16
clac
– Theclac
instruction sets the$ac
to0
. This could be done with a set of stor and sub operations, so instruction is mostly for convenience.$ac <- 0
sub [label/address]
- Subtract a value from data memory to the current$ac
.$ac <- $ac - dm[address]
Either a label or the actual address of the value can be used in this instruction. Thus if the label A refers to the dm address of 5, the following two instructions are the same.
sub A sub 5
subi immediate
- Sub the immediate value in this instruction to the$ac
. The immediate value is an 8-bit integer value between -128...128.$ac <- $ac - immediate
An example of an
subi
instruction which adds 15 to the value in the$ac
follows.subi 15
stor [label/address]
– Store the current value in the $ac to data memory.dm[address] <- $ac
Either a label or the actual address of the value can be used in this instruction. Thus if the label A refers to the dm address of
5
, the following two instructions are the same.stor A stor 5
noop
– this statement does nothing. Executing this statement does not change the value of any memory or registers (except the$pc
) in the system. It is included so that text memory can be set to 0 and executed without changing the internal state of the computer.