mirror of
https://github.com/johnwinans/rvalp.git
synced 2025-09-27 13:12:03 -04:00
Describe ebreak and start addi.
This commit is contained in:
parent
3fbb8f9642
commit
1334c4c199
@ -1,9 +1,14 @@
|
||||
\chapter{Writing RISC-V Programs}
|
||||
|
||||
\enote{Introduce the ISA register names and aliases in here?}%
|
||||
This chapter introduces each of the RV32I instructions by developing programs
|
||||
that demonstrate their usefulness.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Using {\tt ebreak} to Stop \rvddt{} Execution}
|
||||
\section{Use {\tt ebreak} to Stop \rvddt{} Execution}
|
||||
\index{instruction!ebreak}
|
||||
|
||||
The \insn{ebreak} instruction exists for the sole purpose of transferring control back
|
||||
to a debugging environment.\cite[p.~24]{rvismv1v22:2017}
|
||||
@ -29,17 +34,137 @@ I needed for myself \tt:-)}
|
||||
\listing{ebreak/ebreak.out}{\insn{ebreak} stopps \rvddt{} without advancing \reg{pc}.}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Using the \insn{addi} Instruction}
|
||||
\index{instruction!addi}
|
||||
|
||||
\enote{Define what constant and immediate values are somewhere.}%
|
||||
The detailed description of how the \insn{addi} instruction is executed
|
||||
is that it:
|
||||
\begin{enumerate}
|
||||
\item Sign-extends the immediate operand.
|
||||
\item Add the sign-extended immediate operand to the contents of the \reg{rs1} register.
|
||||
\item Store the sum in the \reg{rd} register.
|
||||
\item Add four to the \reg{pc} register (point to the next instruction.)
|
||||
\end{enumerate}
|
||||
|
||||
In the following example \reg{rs1} = \reg{x28}, \reg{rd} = \reg{x29} and
|
||||
the immediate operand is -1.
|
||||
|
||||
\DrawInsnTypeIPicture{addi x29, x28, -1}{11111111111111100000111010010011}
|
||||
|
||||
Depending on the values of the fields in this instruction a number of
|
||||
different operations can be performed. The most obvious is that it
|
||||
can add things. But it can also be used to copy registers, set a
|
||||
register to zero and even, when you need to, accomplish nothing.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{todo}
|
||||
\subsection{No Operation}
|
||||
\index{instruction!nop}
|
||||
|
||||
It might seem odd but it is sometimes important to be able to execute
|
||||
an instruction that accomplishes nothing while simply advancing the
|
||||
\reg{pc} to the next instruction. One reason for this is to fill
|
||||
unused memory between two instructions in a program.%
|
||||
\footnote{This can happen during the evolution of one portion of code
|
||||
that reduces in size but has to continue to fit into a system without
|
||||
altering any other code\ldots\ or some times you just need to waste
|
||||
a small amount of time in a device driver.}
|
||||
|
||||
An instruction that accomplishes nothing is called a \insn{nop}
|
||||
(some times systems call these \insn{noop}). The name means
|
||||
{\em no operation}.
|
||||
The intent of a \insn{nop} is to execute without having any side effects
|
||||
other than to advance the \reg{pc} register.
|
||||
|
||||
The \insn{addi} instruction can serve as a \insn{nop} by coding it like this:
|
||||
|
||||
\DrawInsnTypeIPicture{addi x0, x0, 0}{00000000000000000000000000010011}
|
||||
|
||||
The result will be to add zero to zero and discard the result (because you
|
||||
can never store a value into the x0 register.)
|
||||
|
||||
The RISC-V assembler provides a pseudoinstruction specifically for this
|
||||
purpose that you can use to improve the readability of your code. Note
|
||||
that the \insn{addi} and \insn{nop} instructions in \listingRef{nop/nop.S}
|
||||
are assembled into the exact same binary machine instruction (The
|
||||
\hex{00000013} you can see are stored at addresses \hex{0} and \hex{4})
|
||||
as seen by looking at the objdump listing in \listingRef{nop/nop.lst}.
|
||||
In fact, you can see that objdump shows both instructions as a \insn{nop}
|
||||
while \listingRef{nop/nop.out} shows that \rvddt{} displays both as
|
||||
\verb@addi x0, x0, 0@.
|
||||
|
||||
\listing{nop/nop.S}{Demonstrate that an \insn{addi} can be the same as \insn{nop}.}
|
||||
|
||||
\index{objdump}
|
||||
\listing{nop/nop.lst}{Using \insn{addi} to perform a \insn{nop}}
|
||||
|
||||
\listing{nop/nop.out}{Using \insn{addi} to perform a \insn{nop}}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Copying the Contents of One Register to Another}
|
||||
|
||||
By adding zero to one register and storing the sum in another register
|
||||
the \insn{addi} instruction can be used to copy the value stored in one
|
||||
register to another register. The following instruction will copy
|
||||
the contents of \reg{t4} into \reg{t3}.
|
||||
|
||||
\DrawInsnTypeIPicture{addi t3, t4, 0}{00000000000011101000111000010011}
|
||||
|
||||
\index{instruction!mv}
|
||||
This is a commonly required operation. To make your intent clear
|
||||
you may use the \insn{mv} pseudoinstruction for this purpose.
|
||||
|
||||
\listingRef{mv/mv.S} shows the source of a program that is dumped in
|
||||
\listingRef{mv/mv.lst} illustrating that the assembler has generated the
|
||||
same machine instruction (\hex{000e8e13} at addresses \hex{0} and \hex{4})
|
||||
for both of the instructions.
|
||||
|
||||
\listing{mv/mv.S}{Comparing \insn{addi} to \insn{mv}}
|
||||
|
||||
\listing{mv/mv.lst}{An objdump of an \insn{addi} and \insn{mv} Instruction.}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Setting a Register to Zero}
|
||||
|
||||
Recall that \reg{x0} always contains the value zero. Any register
|
||||
can be set to zero by copying the contents of \reg{x0} using \insn{mv}
|
||||
(aka \insn{addi}).%
|
||||
\footnote{There are other pseudoinstructions (such as \insn{li}) that can also
|
||||
turn into an \insn{addi} instruction. Objdump might display `{\tt addi t3,x0,0}'
|
||||
as `{\tt mv t3,x0}' or `{\tt li t3,0}'.}
|
||||
|
||||
For example, to set \reg{t3} to zero:
|
||||
|
||||
\DrawInsnTypeIPicture{addi t3, x0, 0}{00000000000000000000111000010011}
|
||||
|
||||
\listing{mvzero/mv.S}{Using \insn{mv} (aka \insn{addi}) to zero-out a register.}
|
||||
|
||||
\listingRef{mvzero/mv.out} traces the execution of the program in
|
||||
\listingRef{mvzero/mv.S} showing how \reg{t3} is changed from \hex{f0f0f0f0}
|
||||
(seen on $\ell 16$) to \hex{00000000} (seen on $\ell 26$.)
|
||||
|
||||
\listing{mvzero/mv.out}{Setting \reg{t3} to zero.}
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Adding a 12-bit Signed Value}
|
||||
|
||||
|
||||
\DrawInsnTypeIPicture{addi x1, x7, 4}{00000000010000111000000010010011}
|
||||
|
||||
|
||||
|
||||
|
||||
\enote{Introduce the register names and aliases here.
|
||||
Should we use ISA names or actual names here?}%
|
||||
Ideas for order of introducing operations and instructions.
|
||||
|
||||
\section{Using {\tt addi} to Set Register Values}
|
||||
\begin{verbatim}
|
||||
addi t0, zero, 4 # t0 = 4
|
||||
addi t1, t1, 100 # t1 = 104
|
||||
@ -49,11 +174,20 @@ Ideas for order of introducing operations and instructions.
|
||||
|
||||
addi t0, zero, 0xfff # t0 = 0xffffffff (-1) (diagram out the chaining carry)
|
||||
# refer back to the overflow/truncation discussion in binary chapter
|
||||
|
||||
addi x0, x0, 0 # no operation (pseudo: nop)
|
||||
addi rd, rs, 0 # copy reg rs to rd (pseudo: mv rd, rs)
|
||||
\end{verbatim}
|
||||
|
||||
Demonstrate various addi instructions.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{todo}
|
||||
|
||||
Ideas for the order of introducing instructions.
|
||||
|
||||
|
||||
\section{Other Instructions With Immediate Operands}
|
||||
\begin{verbatim}
|
||||
@ -110,7 +244,7 @@ Copying values from a register to memory:
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\section{Setting values to large values using lui with addi}
|
||||
\section{Setting registers to large values using lui with addi}
|
||||
|
||||
\begin{verbatim}
|
||||
addi // useful for values from -2048 to 2047
|
||||
|
Loading…
x
Reference in New Issue
Block a user