RISC-V Assembly Language Guide
RISC-V Assembly Language Guide
4 John Winans
jwinans@[Link]
5 March 3, 2021
6 Copyright © 2018, 2019, 2020 John Winans
7 This document is made available under a Creative Commons Attribution 4.0 International License.
8 See Appendix D for more information.
9 Download your own copy of this book from github here: [Link]
10 This document may contain inaccuracies or errors. The author provides no guarantee regarding the
11 accuracy of this document’s contents. If you discover that this document contains errors, please notify
12 the author.
13 ý Fix Me:
Need to say something
®
14 ARM is a registered trademark of ARM Limited in the EU and other countries. about trademarks for things
mentioned in this text
15 IBM® is a trademarks or registered trademark of International Business Machines Corporation in the
16 United States, other countries, or both.
17 Intel® and Pentium® are trademarks of Intel Corporation or its subsidiaries in the U.S. and/or other
18 countries.
~/rvalp/book/./[Link] Page i of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
19 Contents
20 Preface iv
21 1 Introduction 1
22 1.1 The Digital Computer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
23 1.2 Instruction Set Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
24 1.3 How the CPU Executes a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
~/rvalp/book/./[Link] Page ii of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
CONTENTS
47 4.11 Relocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
48 4.12 Relaxation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
66 Bibliography 75
67 Glossary 76
68 Index 77
71 I set out to write this book because I couldn’t find it in a single volume elsewhere.
72 The closest published work on this topic appear to be select portions of The RISC-V Instruction Set
73 Manual, Volume I: User-Level ISA, Document Version 2.2[1], The RISC-V Reader[2], and Computer
74 Organization and Design RISC-V Edition: The Hardware Software Interface[3].
75 There are some terse guides on the Internet that are suitable for those who already know an assembly
76 language. With all the (deserved) excitement brewing over system organization (and the need to
77 compress the time out of university courses targeting assembly language programming [4]), it is no
78 surprise that RISC-V texts for the beginning assembly programmer are not (yet) available.
79 When I started in computing, I learned how to count in binary in a high school electronics course using
80 data sheets for integrated circuits such as the 74191[5] and 74154[6] prior to knowing that assembly
81 language even existed.
82 I learned assembly language from data sheets and texts, that are still sitting on my shelves today,
83 such as:
91 All of these manuals discuss each CPU instruction in excruciating detail with both a logical and
92 narrative description. For RISC-V this is also the case for the RISC-V Reader[2] and the Computer
93 Organization and Design RISC-V Edition[3] books and is also present in this text (I consider that to
94 be the minimal level of responsibility.)
95 Where I hope this text will differentiate itself from the existing RISC-V titles is in its attempt to
96 address the needs of those learning assembly language for the first time. To this end I have primed this
97 project with some of the curriculum material I created when teaching assembly language programming
98 in the late ’80s.
~/rvalp/book/./[Link] Page iv of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
99 Chapter 1
100 Introduction
101 At its core, a digital computer has at least one Central Processing Unit (CPU). A CPU executes a
102 continuous stream of instructions called a program. These program instructions are expressed in what
103 is called machine language. Each machine language instruction is a binary value. In order to provide
104 a method to simplify the management of machine language programs a symbolic mapping is provided
105 where a mnemonic can be used to specify each machine instruction and any of its parameters. . .
106 rather than require that programs be expressed as a series of binary values. A set of mnemonics,
107 parameters and rules for specifying their use for the purpose of programming a CPU is called an
108 Assembly Language.
110 There are different types of computers. A digital computer is the type that most people think of when
111 they hear the word computer. Other varieties of computers include analog and quantum.
112 A digital computer is one that processes data represented using numeric values (digits), most com-
113 monly expressed in binary (ones and zeros) form.
115 A typical digital computer is composed of storage systems (memory, disc drives, USB drives, etc.),
116 a CPU (with one or more cores), input peripherals (a keyboard and mouse) and output peripherals
117 (display, printer or speakers.)
119 Computer storage systems are used to hold the data and instructions for the CPU.
120 Types of computer storage can be classified into two categories: volatile and non-volatile.
~/rvalp/book/./intro/[Link] Page 1 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1.1. THE DIGITAL COMPUTER
122 Volatile storage is characterized by the fact that it will lose its contents (forget) any time that it is
123 powered off.
124 One type of volatile storage is provided inside the CPU itself in small blocks called registers. These
125 registers are used to hold individual data values that can be manipulated by the instructions that are
126 executed by the CPU.
127 Another type of volatile storage is main memory (sometimes called RAM) Main memory is connected
128 to a computer’s CPU and is used to hold the data and instructions that can not fit into the CPU
129 registers.
130 Typically, a CPU’s registers can hold tens of data values while the main memory can contain many
131 billions of data values.
132 To keep track of the data values, each register is assigned a number and the main memory is broken
133 up into small blocks called bytes that each assigned a number called an address (an address is often
134 referred to as a location.
135 A CPU can process data in a register at a speed that can be an order of magnitude faster than the
136 rate that it can process (specifically, transfer data and instructions to and from) the main memory.
137 Register storage costs an order of magnitude more to manufacture than main memory. While it is
138 desirable to have many registers, the economics dictate that the vast majority of volatile computer
139 storage be provided in its main memory. As a result, optimizing the copying of data between the
140 registers and main memory is a desirable trait of good programs.
142 Non-volatile storage is characterized by the fact that it will NOT lose its contents when it is powered
143 off.
144 Common types of non-volatile storage are disc drives, ROM flash cards and USB drives. Prices can
145 vary widely depending on size and transfer speeds.
146 It is typical for a computer system’s non-volatile storage to operate more slowly than its main memory.
149 The CPU is a collection of registers and circuitry designed to manipulate the register data and to ý Fix Me:
150 exchange data and instructions with the main memory. The instructions that are read from the Add a block diagram of the
CPU components described
151 main memory tell the CPU to perform various mathematical and logical operations on the data in its here.
152 registers and where to save the results of those operations.
154 The part of a CPU that coordinates all aspects of the operations of each instruction is called the
155 execution unit. It is what performs the transfers of instructions and data between the CPU and
~/rvalp/book/./intro/[Link] Page 2 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1.1. THE DIGITAL COMPUTER
156 the main memory and tells the registers when they are supposed to either store or recall data being
157 transferred. The execution unit also controls the ALU (Arithmetic and Logic Unit).
159 When an instruction manipulates data by performing things like an addition, subtraction, comparison
160 or other similar operations , the ALU is what will calculate the sum, difference, and so on. . . under
161 the control of the execution unit.
163 In the RV32 CPU there are 31 general purpose registers that each contain 32 bits (where each bit is
164 one binary digit value of one or zero) and a number of special-purpose registers. Each of the general
165 purpose registers is given a name such as x1, x2, . . . on up to x31 (general purpose refers to the
166 fact that the CPU itself does not prescribe any particular function to any of these registers.) Two
167 important special-purpose registers are x0 and pc.
168 Register x0 will always represent the value zero or logical false no matter what. If any instruction
169 tries to change the value in x0 the operation will fail. The need for zero is so common that, other
170 than the fact that it is hard-wired to zero, the x0 register is made available as if it were otherwise a
171 general purpose register.1
172 The pc register is called the program counter. The CPU uses it to remember the memory address
173 where its program instructions are located.
174 The number of bits in each register is defined by the Instruction Set Architecture (ISA). ý Fix Me:
Say something about XLEN?
176 Analogous to a core in other types of CPUs, a hart (hardware thread) in a RISC-V CPU refers to the
177 collection of 32 registers, instruction execution unit and ALU.[1, p. 20]
178 When more than one hart is present in a CPU, a different stream of instructions can be executed
179 on each hart all at the same time. Programs that are written to take advantage of this are called
180 multithreaded.
181 This text will primarily focus on CPUs that have only one hart.
183 A peripheral is a device that is not a CPU or main memory. They are typically used to transfer
184 information/data into and out of the main memory.
185 This text is not concerned with the peripherals of a computer system other than in sections where
186 instructions are discussed with the purpose of addressing the needs of a peripheral device. Such
187 instructions are used to initiate, execute and/or synchronize data transfers.
1 Having a special zero register allows the total set of instructions that the CPU can execute to be simplified. Thus
~/rvalp/book/./intro/[Link] Page 3 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1.2. INSTRUCTION SET ARCHITECTURE
189 The catalog of rules that describes the details of the instructions and features that a given CPU
190 provides is called an Instruction Set Architecture (ISA).
191 An ISA is typically expressed in terms of the specific meaning of each binary instruction that a CPU
192 can recognize and how it will process each one.
193 The RISC-V ISA is defined as a set of modules. The purpose of dividing the ISA into modules is to
194 allow an implementer to select which features to incorporate into a CPU design.[1, p. 4]
195 Any given RISC-V implementation must provide one of the base modules and zero or more of the
196 extension modules.[1, p. 4]
198 The base modules are RV32I (32-bit general purpose), RV32E (32-bit embedded), RV64I (64-bit
199 general purpose) and RV128I (128-bit general purpose).[1, p. 4]
200 These base modules provide the minimal functional set of integer operations needed to execute a
201 useful application. The differing bit-widths address the needs of different main-memory sizes.
202 This text primarily focuses on the RV32I base module and how to program it.
204 RISC-V extension modules may be included by an implementer interested in optimizing a design for
205 one or more purposes.[1, p. 4]
206 Available extension modules include M (integer math), A (atomic), F (32-bit floating point), D (64-bit
207 floating point), Q (128-bit floating point), C (compressed size instructions) and others.
208 The extension name G is used to represent the combined set of IMAFD extensions as it is expected
209 to be a common combination.
211 The process of executing a program is continuous repeats of a series of instruction cycles that are each
212 comprised of a fetch, decode and execute phase.
213 The current status of a CPU hart is entirely embodied in the data values that are stored in its registers
214 at any moment in time. Of particular interest to an executing program is the pc register. The pc
215 contains the memory address containing the instruction that the CPU is currently executing.2
216 For this to work, the instructions to be executed must have been previously stored in adjacent main
217 memory locations and the address of the first instruction placed into the pc register.
2 In the RISC-V ISA the pc register points to the current instruction where in most other designs, the pc register
~/rvalp/book/./intro/[Link] Page 4 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1.3. HOW THE CPU EXECUTES A PROGRAM
219 In order to fetch an instruction from the main memory the CPU will update the address in the pc
220 register and then request that the main memory return the value of the data stored at that address.
3
221
223 Once an instruction has been fetched, it must be inspected to determine what operation(s) are to
224 be performed. This means inspecting the portions of the instruction that dictate which registers are
225 involved and what that, if anything, ALU should do.
227 Typical instructions do things like add a number to the value currently stored in one of the registers
228 or store the contents of a register into the main memory at some given address.
230 Most of the time an instruction will complete by indicating that the CPU should proceed to fetch and
231 execute the instruction at the next larger main memory address. In these cases the pc is incremented
232 to point to the memory address after the current instruction.
233 Any parameters that an instruction requires must either be part of the instruction itself or read from
234 (or stored into) one or more of the general purpose registers.
235 Some instructions can specify that the CPU proceed to execute an instruction at an address other
236 than the one that follows itself. This class of instructions have names like jump and branch and are
237 available in a variety of different styles.
238 The RISC-V ISA uses the word jump to refer to an unconditional change in the sequential processing
239 of instructions and the word branch to refer to a conditional change.
240 Conditional branch instructions can be used to tell the CPU to do things like:
241 If the value in x8 is currently less than the value in x24 then proceed to the instruction at
242 the next main memory address, otherwise branch to an instruction at a different address.
243 This type of instruction can therefore result in one of two different actions pending the result of the
244 comparison.4
245 Once the instruction execution phase has completed, the next instruction cycle will be performed
246 using the new value in the pc register.
3 RV32I instructions are more than one byte in size, but this general description is suitable for now.
4 This is the fundamental method used by a CPU to make decisions.
~/rvalp/book/./[Link] Page 5 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
247 Chapter 2
249 This chapter discusses how data are represented and stored in a computer.
250 In the context of computing, boolean refers to a condition that can be either true or false and binary
251 refers to the use of a base-2 numeric system to represent numbers.
252 RISC-V assembly language uses binary to represent all values, be they boolean or numeric. It is the
253 context within which they are used that determines whether they are boolean or numeric.
256 Boolean functions apply on a per-bit basis. When applied to multi-bit values, each bit position is
257 operated upon independent of the other bits.
258 RISC-V assembly language uses zero to represent false and one to represent true. In general, however,
259 it is useful to relax this and define zero and only zero to be false and anything that is not false is
260 therefore true.1
261 The reason for this relaxation is to describe the common case where the CPU processes data, multiple
262 bits at-a-time.
263 These groups have names like byte (8 bits), halfword (16 bits) and fullword (32 bits).
265 The NOT operator applies to a single operand and represents the opposite of the input. ý Fix Me:
Need to define unary, binary
and ternary operators
266 If the input is 1 then the output is 0. If the input is 0 then the output is 1. In other words, the output without confusing binary
267 value is not that of the input value. operators with binary
numbers.
~/rvalp/book/./binary/[Link] Page 6 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.1. BOOLEAN FUNCTIONS
A A
269 0 1
1 0
270 A truth table is drawn by indicating all of the possible input values on the left of the vertical bar
271 with each row displaying the output values that correspond to the input for that row. The column
272 headings are used to define the illustrated operation expressed using a mathematical notation. The
273 not operation is indicated by the presence of an overline.
274 In computer programming languages, things like an overline can not be efficiently expressed using a
275 standard keyboard. Therefore it is common to use a notation such as that used by the C language
276 when discussing the NOT operator in symbolic form. Specifically the tilde: ‘~’.
277 It is also uncommon to for programming languages to express boolean operations on single-bit input(s).
278 A more generalized operation is used that applies to a set of bits all at once. For example, performing
279 a not operation of eight bits at once can be illustrated as:
280 ~ 1 1 1 1 0 1 0 1 <== A
281 -----------------
282 0 0 0 0 1 0 1 0 <== output
283 In a line of code the above might read like this: output = ~A
285 The boolean and function has two or more inputs and the output is a single bit. The output is 1 if
286 and only if all of the input values are 1. Otherwise it is 0.
287 This function works like it does in spoken language. For example if A is 1 and B is 1 then the output
288 is 1 (true). Otherwise the output is 0 (false).
289 In mathematical notion, the and operator is expressed the same way as is multiplication. That is by a
290 raised dot between, or by juxtaposition of, two variable names. It is also worth noting that, in base-2,
291 the and operation actually is multiplication!
A B AB
0 0 0
292 0 1 0
1 0 0
1 1 1
293 This text will use the operator used in the C language when discussing the and operator in symbolic
294 form. Specifically the ampersand: ‘&’.
296 1 1 1 1 0 1 0 1 <== A
297 & 1 0 0 1 0 0 1 1 <== B
298 -----------------
299 1 0 0 1 0 0 0 1 <== output
300 In a line of code the above might read like this: output = A & B
~/rvalp/book/./binary/[Link] Page 7 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.1. BOOLEAN FUNCTIONS
301 2.1.3 OR
302 The boolean or function has two or more inputs and the output is a single bit. The output is 1 if at
303 least one of the input values are 1.
304 This function works like it does in spoken language. For example if A is 1 or B is 1 then the output
305 is 1 (true). Otherwise the output is 0 (false).
306 In mathematical notion, the or operator is expressed using the plus (+).
A B A+B
0 0 0
307 0 1 1
1 0 1
1 1 1
308 This text will use the operator used in the C language when discussing the or operator in symbolic
309 form. Specifically the pipe: ‘|’.
311 1 1 1 1 0 1 0 1 <== A
312 | 1 0 0 1 0 0 1 1 <== B
313 -----------------
314 1 1 1 1 0 1 1 1 <== output
315 In a line of code the above might read like this: output = A | B
317 The boolean exclusive or function has two or more inputs and the output is a single bit. The output
318 is 1 if only an odd number of inputs are 1. Otherwise the output will be 0.
319 Note that when xor is used with two inputs, the output is set to 1 (true) when the inputs have different
320 values and 0 (false) when the inputs both have the same value.
321 In mathematical notion, the xor operator is expressed using the plus in a circle (⊕).
A B A⊕B
0 0 0
322 0 1 1
1 0 1
1 1 0
323 This text will use the operator used in the C language when discussing the xor operator in symbolic
324 form. Specifically the carrot: ‘^’.
~/rvalp/book/./binary/[Link] Page 8 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
326 1 1 1 1 0 1 0 1 <== A
327 ^ 1 0 0 1 0 0 1 1 <== B
328 -----------------
329 0 1 1 0 0 1 1 0 <== output
330 In a line of code the above might read like this: output = A ^ B
332 A binary integer is constructed with only 1s and 0s in the same manner as decimal numbers are
333 constructed with values from 0 to 9.
334 Counting in binary (base-2) uses the same basic rules as decimal (base-10). The difference is when we
335 consider that there are ten decimal digits and only two binary digits. Therefore, in base-10, we must
336 carry when adding one to nine (because there is no digit representing a ten) and, in base-2, we must
337 carry when adding one to one (because there is no digit representing a two.)
338 Figure 2.1 shows an abridged table of the decimal, binary and hexadecimal values ranging from 010
339 to 12910 .
340 One way to look at this table is on a per-row basis where each place value is represented by the
~/rvalp/book/./binary/[Link] Page 9 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
341 base raised to the power of the place value position (shown in the column headings.) For example to
342 interpret the decimal value on the fourth row:
343 Interpreting the binary value on the fourth row by converting it to decimal:
0 × 27 + 0 × 26 + 0 × 25 + 0 × 24 + 0 × 23 + 0 × 22 + 1 × 21 + 1 × 20 = 310 (2.2.2)
344 Interpreting the hexadecimal value on the fourth row by converting it to decimal:
345 We refer to the place values with the largest exponent (the one furthest to the left for any given base)
346 as the most significant digit and the place value with the lowest exponent as the least significant
347 digit. For binary numbers these are the Most Significant Bit (MSB) and Least Significant Bit (LSB)
348 respectively.2
349 Another way to look at this table is on a per-column basis. When tasked with drawing such a table by
350 hand, it might be useful to observe that, just as in decimal, the right-most column will cycle through
351 all of the values represented in the chosen base then cycle back to zero and repeat. (For example, in
352 binary this pattern is 0-1-0-1-0-1-0-. . . ) The next column in each base will cycle in the same manner
353 except each of the values is repeated as many times as is represented by the place value (in the case
354 of decimal, 101 times, binary 21 times, hex 161 times. Again, the binary numbers for this pattern are
355 0-0-1-1-0-0-1-1-. . . ) This continues for as many columns as are needed to represent the magnitude of
356 the desired number.
357 Another item worth noting is that any even binary number will always have a 0 LSB and odd numbers
358 will always have a 1 LSB.
359 As is customary in decimal, leading zeros are sometimes not shown for readability.
360 The relationship between binary and hex values is also worth taking note. Because 24 = 16, there is
361 a clean and simple grouping of 4 bits to 1 hit (aka nybble). There is no such relationship between
362 binary and decimal.
363 Writing and reading numbers in binary that are longer than 8 bits is cumbersome and prone to error.
364 The simple conversion between binary and hex makes hex a convenient shorthand for expressing binary
365 values in many situations.
366 For example, consider the following value expressed in binary, hexadecimal and decimal (spaced to
367 show the relationship between binary and hex):
368 Binary value: 0010 0111 1011 1010 1100 1100 1111 0101
369 Hex Value: 2 7 B A C C F 5
370 Decimal Value: 666553589
371 Empirically we can see that grouping the bits into sets of four allows an easy conversion to hex and
2 Changing the value of the MSB will have a more significant impact on the numeric value than changing the value
of the LSB.
~/rvalp/book/./binary/[Link] Page 10 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
1
372 expressing it as such is 4 as long as in binary while at the same time allowing for easy conversion
373 back to binary.
374 The decimal value in this example does not easily convey a sense of the binary value.
In programming languages like the C, its derivatives and RISC-V assembly, numeric values
are interpreted as decimal unless they start with a zero (0). Numbers that start with 0 are
interpreted as octal (base-8), numbers starting with 0x are interpreted as hexadecimal and
numbers that start with 0b are interpreted as binary.
375
379 To convert from binary to decimal, put the decimal value of the place values . . . 8, 4, 2, 1 over the
380 binary digits like this:
384 Now sum the place-values that are expressed in decimal for each bit with the value of 1: 16 + 8 + 2 + 1.
385 The integer binary value 000110112 represents the decimal value 2710 .
387 Conversion from binary to hex involves grouping the bits into sets of four and then performing the
388 same summing process as shown above. If there is not a multiple of four bits then extend the binary
389 to the left with zeros to make it so.
394 After the summing, convert each decimal value to hex. The decimal values from 0–9 are the same
395 values in hex. Because we don’t have any more numerals to represent the values from 10-15, we use the
396 first 6 letters (See the right-most column of Figure 2.1.) Fortunately there are only six hex mappings
397 involving letters. Thus it is reasonable to memorize them.
399 Decimal: 6 13 10 14
400 Hex: 6 D A E
~/rvalp/book/./binary/[Link] Page 11 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
402 The four-bit mapping between binary and hex makes this task as straight forward as using a look-up
403 table to translate each hit (Hex digIT) it to its unique four-bit pattern.
404 Perform this task either by memorizing each of the 16 patterns or by converting each hit to decimal
405 first and then converting each four-bit binary value to decimal using the place-value summing method
406 discussed in section [Link].
408 Hex: 7 C
409 Decimal Sum: 4+2+1=7 8+4 =12
410 Binary: 0 1 1 1 1 1 0 0
412 To convert arbitrary decimal numbers to binary, extend the list of binary place values until it exceeds
413 the value of the decimal number being converted. Then make successive subtractions of each of the
414 place values that would yield a non-negative result.
430 The answer using this notation is listed vertically in the left column with the MSB on the top and
431 the LSB on the bottom line: 0100110100102 .
433 Conversion from decimal to hex can be done by using the place values for base-16 and the same math
434 as from decimal to binary or by first converting the decimal value to binary and then from binary to
435 hex by using the methods discussed above.
436 Because binary and hex are so closely related, performing a conversion by way of binary is straight
437 forward.
~/rvalp/book/./binary/[Link] Page 12 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
439 The addition of binary numbers can be performed long-hand the same way decimal addition is taught
440 in grade school. In fact binary addition is easier since it only involves adding 0 or 1.
441 The first thing to note that in any number base 0 + 0 = 0, 0 + 1 = 1, and 1 + 0 = 1. Since there is no
442 “two” in binary (just like there is no “ten” decimal) adding 1 + 1 results in a zero with a carry as in:
443 1 + 1 = 102 and in: 1 + 1 + 1 = 112 . Using these five sums, any two binary integers can be added.
444 This truth table shows what is called a Full Addr. A full addr is a function that can add three input
445 bits (the two addends and a carry value from a “prior column”) and produce the sum and carry output
446 values.3
ci a b co sum
0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
447 0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 1
456 There are multiple methods used to represent signed binary integers. The method used by most
457 modern computers is called two’s complement.
458 A two’s complement number is encoded in such a manner as to simplify the hardware used to add,
459 subtract and compare integers.
460 A simple method of thinking about two’s complement numbers is to negate the place value of the
461 MSB. For example, the number one is represented the same as discussed before:
464 The MSB of any negative number in this format will always be 1. For example the value −110 is:
3 Note that the sum could be expressed in Boolean Algebra as: sum = ci ⊕ a ⊕ b
~/rvalp/book/./binary/[Link] Page 13 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
468 This format has the virtue of allowing the same addition logic discussed above to be used to calculate
469 the sums of signed numbers as unsigned numbers.
489 In order for this to work, the carry out of the sum of the MSBs must be discarded.
491 Changing the sign on two’s complement numbers can be described as inverting all of the bits (which
492 is also known as the one’s complement) and then add one.
1 1 <== carries
494
1 1 1 1 1 0 1 1 <== one’s complement of 4
+ 0 0 0 0 0 0 0 1 <== plus 1
----------------------
1 1 1 1 1 1 0 0 <== -4
495 This can be verified by adding 5 to the result and observe that the sum is 1:
~/rvalp/book/./binary/[Link] Page 14 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
496 -128 64 32 16 8 4 2 1
497 1 1 1 1 1 1 <== carries
498 1 1 1 1 1 1 0 0 <== -4
499 + 0 0 0 0 0 1 0 1 <== 5
500 ----------------------
501 1 0 0 0 0 0 0 0 1 <== 1 (with a truncation)
502 Note that the changing of the sign using this method is symmetric in that it is identical when converting
503 from negative to positive and when converting from positive to negative: flip the bits and add 1.
504 For example, changing the value -4 to 4 to illustrate the reverse of the conversion above:
505 -128 64 32 16 8 4 2 1
506 1 1 1 1 1 1 0 0 <== -4
507
514 Subtraction of binary numbers is performed by first negating the subtrahend and then adding the two ý Fix Me:
515 numbers. Due to the nature of two’s complement numbers this method will work for both signed and This section needs more
examples of subtracting
516 unsigned numbers! signed an unsigned numbers
and a discussion on how
signedness is not relevant
517 Observation: Since we always have a carry-in of zero into the LSB when adding, we can take advantage until the results are
518 of that fact by (ab)using that carry input to perform that adding the extra 1 to the subtrahend as interpreted. For example
adding −4 + −8 = −12
519 part of changing its sign in the examples below. using two 8-bit numbers is
the same as adding
520 An example showing the subtraction of two signed binary numbers: −4 − 8 = −12 252 + 248 = 500 and
truncating the result to 244.
521 -128 64 32 16 8 4 2 1
522 1 1 1 1 1 1 0 0 <== -4 (minuend)
523 - 0 0 0 0 1 0 0 0 <== 8 (subtrahend)
524 ------------------------
525
526
533 Discarding the carry bit that can be generated from the MSB is called truncation.
~/rvalp/book/./binary/[Link] Page 15 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
534 So far we have been ignoring the carries that can come from the MSBs when adding and subtracting.
535 We have also been ignoring the potential impact of a carry causing a signed number to change its sign
536 in an unexpected way.
537 In the examples above, truncating the results either had 1) no impact on the calculated sums or 2)
538 was absolutely necessary to correct the sum in cases such as: −4 + 5.
539 For example, note what happens when we try to subtract 1 from the most negative value that we can
540 represent in a 4 bit two’s complement number:
541 -8 4 2 1
542 1 0 0 0 <== -8 (minuend)
543 - 0 0 0 1 <== 1 (subtrahend)
544 ------------
545
546
552 The problem with this example is that we can not represent −910 using a 4-bit two’s complement
553 number.
554 Granted, if we would have used 5 bit numbers, then the “answer” would have fit OK. But the same
555 problem would return when trying to calculate −16 − 1. So simply “making more room” does not
556 solve this problem.
557 This is not just a problem when subtracting, nor is it just a problem with signed numbers.
558 The same situation can happen unsigned numbers. For example:
559 8 4 2 1
560 1 1 1 0 0 <== carries
561 1 1 1 0 <== 14 (addend)
562 + 0 0 1 1 <== 3 (addend)
563 ------------
564 1 0 0 0 1 <== this SHOULD be 17 but with truncation it is 1
565 How to handle such a truncation depends on whether the original values being added are signed or
566 unsigned.
567 The RV ISA refers to the discarding the carry out of the MSB after an add (or subtract) of two
568 unsigned numbers as an unsigned overflow4 and the situation where carries create an incorrect sign in
569 the result of adding (or subtracting) two signed numbers as a signed overflow. [1, p. 13]
571 When adding unsigned numbers, an overflow only occurs when there is a carry out of the MSB resulting
572 in a sum that is truncated to fit into the number of bits allocated to contain the result.
4 Most microprocessors refer to unsigned overflow simply as a carry condition.
~/rvalp/book/./binary/[Link] Page 16 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
1 1 1 1 0 0 0 0 0 <== carries
1 1 1 1 0 0 0 0 <== 240
+ 0 0 0 1 0 0 0 1 <== 17
---------------------
1 0 0 0 0 0 0 0 1 <== sum = 1
Figure 2.2: 240 + 17 = 1 (overflow)
574 Some times an overflow like this is referred to as a wrap around because of the way that successive
575 additions will result in a value that increases until it wraps back around to zero and then returns to
576 increasing in value until it, again, wraps around again.
When adding, unsigned overflow occurs when ever there is a carry out of the most significant
bit.
577
578 When subtracting unsigned numbers, an overflow only occurs when the subtrahend is greater than
579 the minuend (because in those cases the different would have to be negative and there are no negative
580 values that can be represented with an unsigned binary number.)
0 0 0 0 0 0 1 1 <== 3 (minuend)
- 0 0 0 0 0 1 0 0 <== 4 (subtrahend)
-----------------
0 0 0 0 0 0 1 1 1 <== carries
0 0 0 0 0 0 1 1 <== 3
+ 1 1 1 1 1 0 1 1 <== one’s complement of 4
-----------------
1 1 1 1 1 1 1 1 <== 255 (overflow)
Figure 2.3: 3 − 4 = 255 (overflow)
When subtracting, unsigned overflow occurs when ever there is not a carry out of the most
significant bit (IFF the carry-in on the LSB is used to add the extra 1 to the subtrahend when
changing its sign.)
582
584 When adding signed numbers, an overflow only occurs when the two addends are positive and sum is
585 negative or the addends are both negative and the sum is positive.
586 When subtracting signed numbers, an overflow only occurs when the minuend is positive and the
587 subtrahend is negative and difference is negative or when the minuend is negative and the subtrahend
588 is positive and the difference is positive.5
5I had to look it up to remember which were which too. . . it is: minuend - subtrahend = difference.[13]
~/rvalp/book/./binary/[Link] Page 17 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.2. INTEGERS AND COUNTING
589 Consider the results of the addition of two signed numbers while looking more closely at the carry
590 values.
0 1 0 0 0 0 0 0 0 <== carries
0 1 0 0 0 0 0 0 <== 64
+ 0 1 0 0 0 0 0 0 <== 64
---------------------
1 0 0 0 0 0 0 0 <== sum = -128
Figure 2.4: 64 + 64 = −128 (overflow)
591 Figure 2.4 is an example of signed overflow. As shown, the problem is that the sum of two positive
592 numbers has resulted in an obviously incorrect negative result due to a carry flowing into the sign-bit
593 in the MSB.
594 Granted, if the same values were added using values larger than 8-bits then the sum would have been
595 correct. However, these examples assume that all the operations are performed on (and results stored
596 into) 8-bit values. Given any finite-number of bits, there are values that could be added such that an
597 overflow occurs.
598 Figure 2.5 shows another overflow situation that is caused by the fact that there is nowhere for the
599 carry out of the sign-bit to go. We say that this result has been truncated.
1 0 0 0 0 0 0 0 0 <== carries
1 0 0 0 0 0 0 0 <== -128
+ 1 0 0 0 0 0 0 0 <== -128
---------------------
0 0 0 0 0 0 0 0 <== sum = 0
Figure 2.5: −128 + −128 = 0 (overflow)
600 Truncation is not necessarily a problem. Consider the truncations in figures 2.6 and 2.7. Figure 2.7
601 demonstrates the importance of discarding the carry from the sum of the MSBs of signed numbers
602 when addends do not have the same sign.
1 1 1 1 1 1 1 1 0 <== carries
1 1 1 1 1 1 0 1 <== -3
+ 1 1 1 1 1 0 1 1 <== -5
---------------------
1 1 1 1 1 0 0 0 <== sum = -8
Figure 2.6: −3 + −5 = −8
1 1 1 1 1 1 1 0 0 <== carries
1 1 1 1 1 1 1 0 <== -2
+ 0 0 0 0 1 0 1 0 <== 10
---------------------
0 0 0 0 1 0 0 0 <== sum = 8
Figure 2.7: −2 + 10 = 8
603 Just like an unsigned number can wrap around as a result of successive additions, a signed number
604 can so the same thing. The only difference is that signed numbers won’t wrap from the maximum
~/rvalp/book/./binary/[Link] Page 18 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.3. SIGN AND ZERO EXTENSION
605 value back to zero, instead it will wrap from the most positive to the most negative value as shown
606 in Figure 2.8.
0 1 1 1 1 1 1 1 0 <== carries
0 1 1 1 1 1 1 1 <== 127
+ 0 0 0 0 0 0 0 1 <== 1
---------------------
1 0 0 0 0 0 0 0 <== sum = -128
Figure 2.8: 127 + 1 = −128
Formally, a signed overflow occurs when ever the carry into the most significant bit is not the
same as the carry out of the most significant bit.
607
609 Due to the nature of the two’s complement encoding scheme, the following numbers all represent the
610 same value:
615 As do these:
619 The lengthening of these numbers by replicating the digits on the left is what is called sign extension.
Any signed number can have any quantity of additional MSBs added to it, provided that they
repeat the value of the sign bit.
620
621 Figure 2.9 illustrates extending the negative sign bit to the left by replicating it. A negative number
622 will have its MSB (bit 19 in this example) set to 1. Extending this value to the left will set all the
623 new bits to the left of it to 1 as well.
19 0
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
20
31 0
1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
32
~/rvalp/book/./binary/[Link] Page 19 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.4. SHIFTING
624 Figure 2.10 illustrates extending the sign bit of a positive number to the left by replicating it. A
625 positive number will have its MSB set to 0. Extending this value to the left will set all the new bits
626 to the left of it to 0 as well.
19 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
20
31 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
32
627 In a similar vein, any unsigned number also may have any quantity of additional MSBs added to it
628 provided that they are all zero. This is called zero extension. For example, the following all represent
629 the same value:
634 Figure 2.11 illustrates zero-extending a 20-bit number to the left to form a 32-bit number. ý Fix Me:
Remove the sign-bit boxes
19 0
from this figure?
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
20
31 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
32
636 We were all taught how to multiply and divide decimal numbers by ten by moving (or shifting) the
637 decimal point to the right or left respectively. Doing the same in any other base has the same effect
638 in that it will multiply or divide the number by its base.
639 Multiplication and division are only two reasons for shifting. There can be other occasions where ý Fix Me:
640 doing so is useful. Include decimal values in the
shift diagrams.
641 As implemented by a CPU, shifting applies to the value in a register and the results stored back into
642 a register of finite size. Therefore a shift result will always be truncated to fit into a register.
643 Note that when dealing with numeric values, any truncation performed during a right-shift will man- ý Fix Me:
644 ifest itself as rounding toward zero. Add some examples showing
the rounding of positive and
negative values.
~/rvalp/book/./binary/[Link] Page 20 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
646 Shifting logically to the left or right is a matter of re-aligning the bits in a register and truncating the
647 result.
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
20
650
1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
20
652
19 0
0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
20
653
Note that the vacated bit positions are always filled with zero.
654
656 Some times it is desirable to retain the value of the sign bit when shifting. The RISC-V ISA provides
657 an arithmetic right shift instruction for this purpose (there is no arithmetic left shift for this ISA.)
When shifting to the right arithmetically, vacated bit positions are filled by replicating the
value of the sign bit.
658
1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
20
660
19 0
1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0
20
661
663 As mentioned in section [Link], the main memory in a RISC-V system is byte-addressable. For that
664 reason we will visualize it by displaying ranges of bytes displayed in hex and in ASCII. As will become
665 obvious, the ASCII part makes it easier to find text messages.6
6 Most of the memory dumps in this text are generated by rvddt and are shown on a per-byte basis without any
attempt to reorder their values. Some other applications used to dump memory do not dump the bytes in address-order!
It is important to know how your software tools operate when using them to dump the contents of memory and/or files.
~/rvalp/book/./binary/[Link] Page 21 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
667 Listing 2.1 shows a memory dump from the rvddt ‘d’ command requesting a dump starting at address
668 0x00002600 for the default quantity (0x100) of bytes.
Listing 2.1: rvddt_memdump.out
rvddt memory dump
669
670 1 ddt > d 0 x00002600
671 2 00002600: 93 05 00 00 13 06 00 00 93 06 00 00 13 07 00 00 *................*
672 3 00002610: 93 07 00 00 93 08 d0 05 73 00 00 00 63 54 05 02 *........ s ... cT ..*
673 4 00002620: 13 01 01 ff 23 24 81 00 13 04 05 00 23 26 11 00 *....# $ ......#&..*
674 5 00002630: 33 04 80 40 97 00 00 00 e7 80 40 01 23 20 85 00 *3.. @ ...... @ .# ..*
675 6 00002640: 6 f 00 00 00 6f 00 00 00 b7 87 00 00 03 a5 07 43 * o ... o .......... C *
676 7 00002650: 67 80 00 00 00 00 00 00 76 61 6c 3d 00 00 00 00 * g ....... val =....*
677 8 00002660: 00 00 00 00 80 84 2e 41 1f 85 45 41 80 40 9a 44 *....... A .. EA . @ . D *
678 9 00002670: 4 f 11 f3 c3 6e 8a 67 41 20 1b 00 00 20 1b 00 00 * O ... n . gA ... ...*
679 10 00002680: 44 1 b 00 00 14 1b 00 00 14 1b 00 00 04 1c 00 00 * D . . . . . . . . . . . .. . . *
680 11 00002690: 44 1 b 00 00 14 1b 00 00 04 1c 00 00 14 1b 00 00 * D . . . . . . . . . . . .. . . *
681 12 000026 a0 : 44 1 b 00 00 10 1b 00 00 10 1b 00 00 10 1b 00 00 *D ...............*
682 13 000026 b0 : 04 1 c 00 00 54 1f 00 00 54 1f 00 00 d4 1f 00 00 *.... T ... T .......*
683 14 000026 c0 : 4 c 1 f 00 00 4c 1f 00 00 34 20 00 00 d4 1f 00 00 * L ... L ...4 ......*
684 15 000026 d0 : 4 c 1 f 00 00 34 20 00 00 4c 1f 00 00 d4 1f 00 00 * L ...4 .. L .......*
685 16 000026 e0 : 48 1 f 00 00 48 1f 00 00 48 1f 00 00 34 20 00 00 * H ... H ... H ...4 ..*
686
687
17 000026 f0 : 00 01 02 02 03 03 03 03 04 04 04 04 04 04 04 04 *................*
701 The choice of which end of a multi-byte value is to be stored at the lowest byte address is referred to as
702 endianness. For example, if a CPU were to store a halfword into memory, should the byte containing
703 the Most Significant Bit (MSB) (the big end) go first or does the byte with the Least Significant Bit
704 (LSB) (the little end) go first?
705 On the one hand the choice is arbitrary. On the other hand, it is possible that the choice could impact
706 the performance of the system.7
707 IBM mainframe CPUs and the 68000 family store their bytes in big-endian order. While the Intel
708 Pentium and most embedded processors use little-endian order. Some CPUs are even bi-endian in
709 that they have instructions that can change their order on the fly.
~/rvalp/book/./binary/[Link] Page 22 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
712 Using the contents of Listing 2.1, a big-endian CPU would interpret the contents as follows:
713 • The 8-bit value read from address 0x00002658 would be 0x76.
714 • The 8-bit value read from address 0x00002659 would be 0x61.
715 • The 8-bit value read from address 0x0000265a would be 0x6c.
716 • The 8-bit value read from address 0x0000265b would be 0x3d.
717 • The 16-bit value read from address 0x00002658 would be 0x7661.
718 • The 16-bit value read from address 0x0000265a would be 0x6c3d.
719 • The 32-bit value read from address 0x00002658 would be 0x76616c3d.
720 Notice that in a big-endian system, the place values of the bits comprising the 0x76 (located at memory
721 address 0x00002658 ) are different depending on the number of bytes representing the value that is
722 being read.
723 For example, when a 16-bit value is read from 0x00002658 then the 76 represents the binary place
724 values: 215 to 28 . When a 32-bit value is read then the 76 represents the binary place values: 231 to
725 224 . In other words the value read from the first memory location (with the lowest address), of the
726 plurality of addresses containing the complete value being read, is always placed on the left end, into
727 the Most Significant Bits. One might dare say that the 76 is placed at the end with the big place
728 values.
737 Again, notice that the byte from memory address 0x00002624 , regardless of the number of bytes
738 comprising the complete value being fetched, will always appear on the left/big end of the final value.
On a big-endian system, the bytes in the dump are in the same order as they would be used
by the CPU if it were to read them as a multi-byte value.
739
~/rvalp/book/./binary/[Link] Page 23 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
741 Using the contents of Listing 2.1, a little-endian CPU would interpret the contents as follows:
749 Notice that in a little-endian system, the place values of the bits comprising the 0x76 (located at
750 memory address 0x00002658 ) are the same regardless of the the number of bytes representing the
751 value that is being read.
752 Unlike the behavior of a big-endian machine, when little-endian machine reads a 16-bit value from
753 0x00002658 the 76 represents the binary place values from 27 to 20 . When a 32-bit value is read
754 then the 76 (still) represents the binary place values from 27 to 20 . In other words the value read
755 from the first memory location (with the lowest address), of the plurality of addresses containing the
756 complete value being read, is always placed on the right end, into the Least Significant Bits. One
757 might say that the 76 is placed at the end with the little place values.
758 Also notice that it is the bytes are what are “reversed” in a little-endian system (not the hex digits.)
760 • The 8-bit value read from address 0x00002624 would be 0x23.
761 • The 8-bit value read from address 0x00002625 would be 0x24.
762 • The 8-bit value read from address 0x00002626 would be 0x81.
763 • The 8-bit value read from address 0x00002627 would be 0x00.
764 • The 16-bit value read from address 0x00002624 would be 0x2423.
765 • The 16-bit value read from address 0x00002626 would be 0x0081.
766 • The 32-bit value read from address 0x00002624 would be 0x00812423.
767 As above, notice that the byte from memory address 0x00002624 , regardless of the number of bytes
768 comprising the complete value being fetched, will always appear on the right/little end of the final
769 value.
On a little-endian system, the bytes in the dump are in reverse order as they would be used
by the CPU if it were to read them as a multi-byte value.
770
~/rvalp/book/./binary/[Link] Page 24 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
772 A minor point is that we have also found little-endian memory systems to be more natural
773 for hardware designers. However, certain application areas, such as IP networking, operate
774 on big-endian data structures, and so we leave open the possibility of non-standard big-
775 endian or bi-endian systems.”[1, p. 6]
777 While Endianness defines how single values are stored in memory, the array defines how multiple
778 values are stored.
779 An array is a data structure comprised of an ordered set of elements. This text will limit its definition
780 of array to a plurality of elements that are all of the same type. Where type refers to the size (number
781 of bytes) and representation (signed, unsigned,. . . ) of each element.
782 In an array, the elements are stored adjacent to one another such that the address e of any element
783 x[n] is:
e=a+n∗s (2.5.1)
784 Where x is the name of the array, n is the element number of interest, e is the address of interest, a
785 is the address of the first element in the array and s is the size (in bytes) of each element.
786 Given an array x containing m elements, x[0] is the first element of the array and x[m − 1] is the last
787 element of the array.8
788 Using this definition, and the memory dump shown in Listing 2.1, and the knowledge that we are
789 using a little-endian machine and given that a = 0x00002656 and s = 2, the values of the first 8
790 elements of array x are:
In general, there is no fixed rule nor notion as to how many elements an array has. It is up to
the programmer to ensure that the starting address and the number of elements in any given
array (its size) are used properly so that data bytes outside an array are not accidentally used
as elements.
799
8 Some computing languages (C, C++, Java, C#, Python, Perl,. . . ) define an array such that the first element is
indexed as x[0]. While others (FORTRAN, MATLAB) define the first element of an array to be x[1].
~/rvalp/book/./binary/[Link] Page 25 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
800 There is, however, a common convention used for an array of characters that is used to hold a text
801 message (called a character string or just string).
802 When an array is used to hold a string the element past the last character in the string is set to zero.
803 This is because 1) zero is not a valid printable ASCII character and 2) it simplifies software in that
804 knowing no more than the starting address of a string is all that is needed to processes it. Without
805 this zero sentinel value (called a null terminator), some knowledge of the number of characters in the
806 string would have to otherwise be conveyed to any code needing to consume or process the string.
807 In Listing 2.1, the 5-byte long array starting at address 0x00002658 contains a string whose value can
808 be expressed as either:
809 76 61 6c 3d 00
810 or
811 "val="
812 When the double-quoted text form is used, the GNU assembler used in this text differentiates between
813 ascii and asciiz strings such that an ascii string is not null terminated and an asciiz string is null
814 terminated.
815 The value of providing a method to create a string that is not null terminated is that a program may
816 define a large string by concatenating a number of ascii strings together and following the last with
817 a byte of zero to null-terminate it.
818 It is a common mistake to create a string with a missing null terminator. The result of printing such
819 a string is that the string will be printed as well as whatever random data bytes in memory follow it
820 until a byte whose value is zero is encountered by chance.
822 Data values can be interpreted differently depending on the context in which they are used. Assuming
823 what a set of bytes is used for based on their contents can be very misleading! For example, there is
824 a 0x76 at address 0x00002658. This is a ‘v’ is you use it as an ASCII (see Appendix C) character, a
825 11810 if it is an integer value and TRUE if it is a conditional.
827 With respect to memory and storage, alignment refers to the location of a data element when the ý Fix Me:
828 address that it is stored is a precise multiple of a power-of-2. Include the obligatory
diagram showing the
overlapping data types when
829 The primary alignments of concern are typically 2 (a halfword), 4 (a fullword), 8 (a double word) and they are all aligned.
830 16 (a quad-word) bytes.
831 For example, any data element that is aligned to 2-byte boundary must have an (hex) address that
832 ends in any of: 0, 2, 4, 6, 8, A, C or E. Any 4-byte aligned element must be located at an address
833 ending in 0, 4, 8 or C. An 8-byte aligned element at an address ending with 0 or 8, and 16-byte aligned
834 elements must be located at addresses ending in zero.
835 Such alignments are important when exchanging data between the CPU and memory because the
836 hardware implementations are optimized to transfer aligned data. Therefore, aligning data used by
~/rvalp/book/./binary/[Link] Page 26 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2.5. MAIN MEMORY STORAGE
838 An element of data is considered to be aligned to its natural size when its address is an exact multiple
839 of the number of bytes used to represent the data. Note that the ISA we are concerned with only
840 operates on elements that have sizes that are powers of two.
841 For example, a 32-bit integer consumes one full word. If the four bytes are stored in main memory at
842 an address than is a multiple of 4 then the integer is considered to naturally aligned.
843 The same would apply to 16-bit, 64-bit, 128-bit and other such values as they fit into 2, 8 and 16 byte
844 elements respectively.
845 Some CPUs can deliver four (or more) bytes at the same time while others might only be capable
846 of delivering one or two bytes at a time. Such differences in hardware typically impact the cost and
847 performance of a system.10
849 The RISC-V ISA requires that all instructions be aligned to their natural boundaries.
850 Every possible instruction that an RV32I CPU can execute contains exactly 32 bits. Therefore they
851 are always stored on a full word boundary. Any unaligned instruction is illegal.11
852 An attempt to fetch an instruction from an unaligned address will result in an error referred to as
853 an alignment exception. This and other exceptions cause the CPU to stop executing the current
854 instruction and start executing a different set of instructions that are prepared to handle the problem.
855 Often an exception is handled by completely stopping the program in a way that is commonly referred
856 to as a system or application crash.
9 Alignment of data, while important for efficient performance, is not mandatory for RISC-V systems.[1, p. 19]
10 The design and implementation choices that determine how any given system operates are part of what is called a
system’s organization and is beyond the scope of this text. See [3] for more information on computer organization.
11 This rule is relaxed by the C extension to allow an instruction to start at any even address.[1, p. 5]
~/rvalp/book/./[Link] Page 27 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
857 Chapter 3
866 Is this a good place to introduce the text, data, bss, heap and stack regions?
867 Or does that belong in a new section/chapter that discusses addressing modes?
869 A simple program that illustrates how this text presents program source code is seen in Listing 3.1.
870 This program will place a zero in each of the 4 registers named x28, x29, x30 and x31.
Listing 3.1: zero4regs.S
Setting four registers to zero.
871
872 1 . text # put this into the text section
873 2 . align 2 # align to 2^2
874 3 . globl _start
875 4 _start :
876 5 addi x28 , x0 , 0 # set register x28 to zero
877 6 addi x29 , x0 , 0 # set register x29 to zero
878 7 addi x30 , x0 , 0 # set register x30 to zero
879
880
8 addi x31 , x0 , 0 # set register x31 to zero
~/rvalp/book/./elements/[Link] Page 28 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
3.4. RUNNING A PROGRAM WITH RVDDT
882 • Listings are identified by the name of the file within which they are stored. This listing is from
883 a file named: zero4regs.S.
884 • The assembly language programs discussed in this text will be saved in files that end with: .S
885 (Alternately you can use .sx on systems that don’t understand the difference between upper
886 and lowercase letters.1 )
887 • A description of the listing’s purpose appears under the name of the file. The description of
888 Listing 3.1 is Setting four registers to zero.
889 • The lines of the listing are numbered on the left margin for easy reference.
890 • An assembly program consists of lines of plain text.
891 • The RISC-V ISA does not provide an operation that will simply set a register to a numeric
892 value. To accomplish our goal this program will add zero to zero and place the sum in in each
893 of the four registers.
894 • The lines that start with a dot ‘.’ (on lines 1, 2 and 3) are called assembler directives as they
895 tell the assembler itself how we want it to translate the following assembly language instructions
896 into machine language instructions.
897 • Line 4 shows a label named start. The colon at the end is the indicator to the assembler that
898 causes it to recognize the preceding characters as a label.
899 • Lines 5-8 are the four assembly language instructions that make up the program. Each instruc-
900 tion in this program consists of four fields. (Different instructions can have a different number
901 of fields.) The fields on line 5 are:
902 addi The instruction mnemonic. It indicates the operation that the CPU will perform.
903 x28 The destination register that will receive the sum when the addi instruction is finished.
904 The names of the 32 registers are expressed as x0 – x31.
905 x0 One of the addends of the sum operation. (The x0 register will always contain the value
906 zero. It can never be changed.)
907 0 The second addend is the number zero.
908 # set . . . Any text anywhere in a RISC-V assembly language program that starts with the pound-
909 sign is ignored by the assembler. They are used to place a comment in the program to help
910 the reader better understand the motive of the programmer.
912 To illustrate what a CPU does when it executes instructions this text will use the rvddt simulator to
913 display shows sequence of events and the binary values involved. This simulator supports the RV32I
914 ISA and has a configurable amount of memory.2
915 Listing 3.2 shows the operation of the four addi instructions from Listing 3.1 when it is executed in
916 trace-mode.
1 Theauthor of this text prefers to avoid using such systems.
2 Thervddt simulator was written to generate the listings for this text. It is similar to the fancier spike simulator.
Given the simplicity of the RV32I ISA, rvddt is less than 1700 lines of C++ and was written in one (long) afternoon.
~/rvalp/book/./[Link] Page 29 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
3.4. RUNNING A PROGRAM WITH RVDDT
954 ` 1 This listing includes the command-line that shows how the simulator was executed to load a file
955 containing the machine instructions (aka machine code) from the assembler.
956 ` 2 A message from the simulator indicating that it loaded the machine code into simulated memory
957 at address 0.
958 ` 3 This line shows the prompt from the debugger and the command t4 that the user entered to
959 request that the simulator trace the execution of four instructions.
960 ` 4-8 Prior to executing the first instruction, the state of the CPU registers is displayed.
961 ` 4 The values in registers 0, 1, 2, 3, 4, 5, 6 and 7 are printed from left to right in big-endian,
962 hexadecimal form. The double-space gap in the middle of the line is a reference to make it
963 easier to visually navigate across the line without being forced to count the values from the far
964 left when seeking the value of, say, x5.
965 ` 5-7 The values of registers 8–31 are printed.
966 ` 8 The program counter (pc) register is printed. It contains the address of the instruction that the
967 CPU will execute. After each instruction, the pc will either advance four bytes ahead or be set
968 to another value by a branch instruction as discussed above.
969 ` 9 A four-byte instruction is fetched from memory at the address in the pc register, is decoded and
970 printed. From left to right the fields shown on this line are:
~/rvalp/book/./elements/[Link] Page 30 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
3.4. RUNNING A PROGRAM WITH RVDDT
971 00000000 The memory address from which the instruction was fetched. This address is displayed in
972 big-endian, hexadecimal form.
973 00000e13 The machine code of the instruction displayed in big-endian, hexadecimal form.
974 addi The mnemonic for the machine instruction.
975 x28 The rd field of the addi instruction.
976 x0 The rs1 field of the addi instruction that holds one of the two addends of the operation.
977 0 The imm field of the addi instruction that holds the second of the two addends of the
978 operation.
979 # . . . A simulator-generated comment that explains what the instruction is doing. For this in-
980 struction it indicates that x28 will have the value zero stored into it as a result of performing
981 the addition: 0 + 0.
982 ` 10-14 These lines are printed as the prelude while tracing the second instruction. Lines 7 and 13 show
983 that x28 has changed from f0f0f0f0 to 00000000 as a result of executing the first instruction and
984 lines 8 and 14 show that the pc has advanced from zero (the location of the first instruction) to
985 four, where the second instruction will be fetched. None of the rest of the registers have changed
986 values.
987 ` 15 The second instruction decoded executed and described. This time register x29 will be assigned
988 a value.
989 ` 16-27 The third and fourth instructions are traced.
990 ` 28 Tracing has completed. The simulator prints its prompt and the user enters the ‘r’ command
991 to see the register state after the fourth instruction has completed executing.
992 ` 29-33 Following the fourth instruction it can be observed that registers x28, x29, x30 and x31 have
993 been set to zero and that the pc has advanced from zero to four, then eight, then 12 (the hex
994 value for 12 is c) and then to 16 (which, in hex, is 10).
995 ` 34 The simulator exit command ‘x’ is entered by the user and the terminal displays the shell prompt.
~/rvalp/book/./[Link] Page 31 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
996 Chapter 4
998 This chapter introduces each of the RV32I instructions by developing programs that demonstrate their ý Fix Me:
999 usefulness. Introduce the ISA register
names and aliases in here?
1001 It is a good idea to learn how to stop before learning how to go!
1002 The ebreak instruction exists for the sole purpose of transferring control back to a debugging environment.[1,
1003 p. 24]
1004 When rvddt executes an ebreak instruction, it will immediately terminate any executing trace or go
1005 command currently executing and return to the command prompt without advancing the pc register.
1006 The machine language encoding shows that ebreak has no operands.
1007 ebreak
31 20 19 15 14 12 11 7 6 0
funct3 opcode
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 I-type
12 5 3 5 7
1008
1009 Listing 4.2 demonstrates that since rvddt does not advance the pc when it encounters an ebreak
1010 instruction, subsequent trace and/or go commands will re-execute the same ebreak and halt the
1011 simulation again (and again). This feature is intended to help prevent overzealous users from accidently
1012 running past the end of a code fragment.1
1 This was one of the first enhancements I needed for myself :-)
~/rvalp/book/./programs/[Link] Page 32 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.2. USING THE ADDI INSTRUCTION
1049 The detailed description of how the addi instruction is executed is that it: ý Fix Me:
Define what constant and
immediate values are
somewhere.
1050 1. Sign-extends the immediate operand.
1051 2. Add the sign-extended immediate operand to the contents of the rs1 register.
1052 3. Store the sum in the rd register.
1053 4. Add four to the pc register (point to the next instruction.)
1054 In the following example rs1 = x28, rd = x29 and the immediate operand is -1.
1057 Depending on the values of the fields in this instruction a number of different operations can be
1058 performed. The most obvious is that it can add things. But it can also be used to copy registers, set
1059 a register to zero and even, when you need to, accomplish nothing.
1061 It might seem odd but it is sometimes important to be able to execute an instruction that accomplishes
1062 nothing while simply advancing the pc to the next instruction. One reason for this is to fill unused
~/rvalp/book/./programs/[Link] Page 33 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.2. USING THE ADDI INSTRUCTION
1064 An instruction that accomplishes nothing is called a nop (sometimes systems call these noop). The
1065 name means no operation. The intent of a nop is to execute without having any side effects other
1066 than to advance the pc register.
1067 The addi instruction can serve as a nop by coding it like this:
1070 The result will be to add zero to zero and discard the result (because you can never store a value into
1071 the x0 register.)
1072 The RISC-V assembler provides a pseudoinstruction specifically for this purpose that you can use
1073 to improve the readability of your code. Note that the addi and nop instructions in Listing 4.3 are
1074 assembled into the exact same binary machine instructions as can be seen by comparing it to objdump
1075 Listing 4.4, and rvddt Listing 4.5 output.
a system without altering any other code. . . or sometimes you just need to waste a small amount of time in a device
driver.
~/rvalp/book/./nop/[Link] Page 34 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.2. USING THE ADDI INSTRUCTION
1107 12 pc 00000000
1108 13 ddt > ti 0 1000
1109 14 00000000: 00000013 addi x0 , x0 , 0 # x0 = 0 x00000000 = 0 x00000000 + 0 x00000000
1110 15 00000004: 00000013 addi x0 , x0 , 0 # x0 = 0 x00000000 = 0 x00000000 + 0 x00000000
1111 16 00000008: ebreak
1112 17 ddt > r
1113 18 x0 00000000 f0f0f0f0 0000 fff0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
1114 19 x8 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
1115 20 x16 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
1116 21 x24 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
1117 22 pc 00000008
1118
1119
23 ddt > x
1121 By adding zero to one register and storing the sum in another register the addi instruction can be
1122 used to copy the value stored in one register to another register. The following instruction will copy
1123 the contents of t4 into t3.
1126 This is a commonly required operation. To make your intent clear you may use the mv pseudoinstruc-
1127 tion for this purpose.
1128 Listing 4.6 shows the source of a program that is dumped in Listing 4.7 illustrating that the assembler
1129 has generated the same machine instruction (0x000e8e13 at addresses 0x0 and 0x4) for both of the
1130 instructions.
Listing 4.6: mv/mv.S
Comparing addi to mv
1131
1132 1 . text # put this into the text section
1133 2 . align 2 # align to a multiple of 4
1134 3 . globl _start
1135 4
1136 5 _start :
1137 6 addi t3 , t4 , 0 # t3 = t4
1138 7 mv t3 , t4 # t3 = t4
1139 8
1140
1141
9 ebreak
~/rvalp/book/./programs/[Link] Page 35 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.2. USING THE ADDI INSTRUCTION
1151 Recall that x0 always contains the value zero. Any register can be set to zero by copying the contents
1152 of x0 using mv (aka addi).3
1166 Listing 4.9 traces the execution of the program in Listing 4.8 showing how t3 is changed from
1167 0xf0f0f0f0 (seen on `16) to 0x00000000 (seen on `26.)
3 There are other pseudoinstructions (such as li) that can also turn into an addi instruction. Objdump might display
~/rvalp/book/./programs/[Link] Page 36 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.3. TODO
1208 addi t0, zero, 0xfff # t0 = 0xffffffff (-1) (diagram out the chaining carry)
1209 # refer back to the overflow/truncation discussion in binary chapter
1210
1216 andi
1217 ori
1218 xori
1219
1220 slti
1221 sltiu
1222 srai
1223 slli
1224 srli
1226 RV is a load-store architecture. This means that the only way that the CPU can interact with the
1227 memory is via the load and store instructions. All other data manipulation must be performed on
1228 register values.
1229 Copying values from memory to a register (first examples using regs set with addi):
1230 lb
1231 lh
1232 lw
1233 lbu
1234 lhu
~/rvalp/book/./programs/[Link] Page 37 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.6. RR OPERATIONS
1236 sb
1237 sh
1238 sw
1240 add
1241 sub
1242 and
1243 or
1244 sra
1245 srl
1246 sll
1247 xor
1248 sltu
1249 slt
1250 4.7 Setting registers to large values using lui with addi
1254 Setting a register to any other value must be done using a combo of insns:
1255
1256 auipc // Load an address relative the the current PC (see la pseudo)
1257 addi
1258
1259 lui // Load constant into into bits 31:12 (see li pseudo)
1260 addi // add a constant to fill in bits 11:0
1261 if bit 11 is set then need to +1 the lui value to compensate
1264 beq
1265 bne
1266 blt
1267 bge
1268 bltu
1269 bgeu
1270
1271 bgt rs, rt, offset # pseudo for: blt rt, rs, offset (reverse the operands)
1272 ble rs, rt, offset # pseudo for: bge rt, rs, offset (reverse the operands)
1273 bgtu rs, rt, offset # pseudo for: bltu rt, rs, offset (reverse the operands)
1274 bleu rs, rt, offset # pseudo for: bgeu rt, rs, offset (reverse the operands)
1275
~/rvalp/book/./programs/[Link] Page 38 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.9. JUMPS
1276 beqz rs, offset # pseudo for: beq rs, x0, offset
1277 bnez rs, offset # pseudo for: bne rs, x0, offset
1278 blez rs, offset # pseudo for: bge x0, rs, offset
1279 bgez rs, offset # pseudo for: bge rs, x0, offset
1280 bltz rs, offset # pseudo for: blt rs, x0, offset
1281 bgtz rs, offset # pseudo for: blt x0, rs, offset
1283 Introduce and present subroutines but not nesting until introduce stack operations.
1284 jal
1285 jalr
1290 la rd,label
1291 auipc rd,((label-.) >>U 12) + ((label-.) & 0x00000800 ? 1 : 0)
1292 addi rd,rd,((label-(.-4)) & 0xfff)
1293
1298 s{b|h|w} rd,label,rt # rt used as a temp reg for the operation (default=x6)
1299 auipc rt,((label-.) >>U 12) + ((label-.) & 0x00000800 ? 1 : 0)
1300 s{b|h|w} rd,((label-(.-4)) & 0xfff)(rt)
1301
1302 call label auipc x1,((label-.) >>U 12) + ((label-.) & 0x00000800 ? 1 : 0)
1303 jalr x1,((label-(.-4)) & 0xfff)(x1)
1304
1305 tail label,rt # rt used as a temp reg for the operation (default=x6)
1306 auipc rt,((label-.) >>U 12) + ((label-.) & 0x00000800 ? 1 : 0)
1307 jalr x0,((label-(.-4)) & 0xfff)(rt)
1308
1317 Note that the li pseudoinstruction includes a conditional addition of 1 to the operand in the lui
1318 instruction. This is because the immediate operand in the addi instruction is sign-extended before it
~/rvalp/book/./programs/[Link] Page 39 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.10. PSEUDOINSTRUCTIONS
1319 is added to rd. If the immediate operand to the addi has its most-significant-bit set to 1 then it will
1320 have the effect of subtracting 1 from the operand in the lui instruction.
1321 Consider the case of putting the value 0x12345800 into register x5:
1322 li x5,0x12345800
1326 The result of the above code is that an incorrect value has been placed into x5.
1327 To remedy this problem, the value used in the lui instruction can altered (by adding 1 to its operand)
1328 to compensate for the sign-extention in the addi instruction:
1331 Keep in mind that the only time that this altering of the operand in the lui instruction should take
1332 place is when the most-significant-bit of the operand in the addi is set to one.
1333 Consider the case where we wish to put the value 0x12345700 into register x5:
1336 The sign-extension in this example performed by the addi instruction will convert the 0x700 to
1337 0x00000700 before the addition.
1338 Therefore, the li pseudoinstruction must only increment the operand of the lui instruction when it
1339 is known that the operand of the subsequent addi instruction will be a negative number.
1341 The la (and others that use auipc such as the l{b|h|w}, s{b|h|w}, call, and tail) pseudoinstruc-
1342 tions also compensate for a sign-ended negative number when adding a 12-bit immediate operand.
1343 The only difference is that these use a pc-relative addressing mode.
1344 For example, consider the task of putting an address represented by the label var1 into register x10:
1349 var1:
1350 00010900 .word 999 # a 32-bit integer constant stored in memory at address var1
~/rvalp/book/./programs/[Link] Page 40 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.11. RELOCATION
1354 Note that auipc will shift the immediate operand to the left 12 bits and then add that to the pc
1355 register (see Figure 5.3.1.)
1356 The assembler will calculate the value of (var1-.) by subtracting the address represented by the label
1357 var1 from the address of the current instruction (which is expressed as ’.’) resulting in the number
1358 of bytes from the current instruction to the target label. . . which is 0x000008c0.
1366 00010040 auipc x10,0x00000 + 1 # add 1 here because 0x8c0 below has MSB = 1
1367 00010044 addi x10,x10,0x8c0
1368 . . . and. . .
1371 Note that the the la exhibits the same sort of technique as the li in that if/when the immediate
1372 operand of the addi instruction has its most significant bit set then the operand in the auipc has to
1373 be incremented by 1 to compensate.
1375 Because expressions that refer to constants and address labels are common in assembly language
1376 programs, a shorthand notation is available for calculating the pairs of values that are used in the
1377 implementation of things like the li and la pseudoinstructions (that have to be written to compensate
1378 for the sign-extension that will take place in the immediate operand that appears in instructions like
1379 addi and jalr.)
~/rvalp/book/./programs/[Link] Page 41 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
4.12. RELAXATION
1391 Note the subtlety involved with the lab on %pcrel_lo. It is needed to determine the address of the
1392 instruction that contains the corresponding %pcrel_hi. (The label lab MUST be on a line that used
1393 a %pcrel_hi() or get an error from the assembler.)
1397 Examples of using the auipc & addi together with %pcrel_hi() and %pcrel_lo():
1398 xxx: auipc t1,%pcrel_hi(yyy) // (yyy-xxx) >>U 12) + ((yyy-xxx) & 0x00000800 ? 1 : 0)
1399 addi t1,t1,%pcrel_lo(xxx) // ((yyy-xxx) & 0xfff)
1400 ...
1401 yyy: // the address: yyy is saved into t1 above
1402 ...
1410 In the simplest of terms, Relaxation refers to the ability of the linker (not the compiler!) to determine ý Fix Me:
1411 if/when the instructions that were generated with the xxx_hi and xxx_lo operators are unneeded I’m not sure I want to get
into the details of how this is
1412 (and thus waste execution time and memory) and can therefore be removed. done. Just assume it works.
1413 However, doing so is not trivial as it will result in moving things around in memory, possibly changing
1414 the values of address labels in the already-assembled program! Therefore, while the motivation for
1415 rexation is obvious, the process of implementing it is non-trivial.
~/rvalp/book/./[Link] Page 42 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1417 Chapter 5
1422 XLEN represents the bit-length of an x register in the machine architecture. Possible values are 32,
1423 64 and 128.
1426 This is used to convert a signed integer value expressed using some number of bits to a larger number
1427 of bits by adding more bits to the left. In doing so, the sign will be preserved. In this case val
1428 represents the least MSBs of the value.
1432 This is used to convert an unsigned integer value expressed using some number of bits to a larger
1433 number of bits by adding more bits to the left. In doing so, the new bits added will all be set to zero.
1434 As is the case with sx(val), val represents the LSBs of the final value.
~/rvalp/book/./rv32/[Link] Page 43 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.1. CONVENTIONS AND TERMINOLOGY
1438 Some times a binary value is encoded such that a set of bits represented by val are used to represent
1439 the MSBs of some longer (more bits) value. In this case it is necessary to append zeros to the right
1440 to convert val to the longer value.
19 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
20
31 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
32
1443 Some instructions such as the J-type (see section 5.3.2) include immediate operands that are extended
1444 in both directions.
1445 Figure 5.2 and Figure 5.3 illustrates zero-extending a 20-bit negative number one bit to the right and
1446 sign-extending it 11 bits to the left:
19 0
0 1 0 0 0 1 0 0 0 1 1 1 0 1 0 0 1 0 0 1
20
31 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 1 0 1 0 0 1 0 0 1 0
32
Figure 5.2: Sign-extending a positive 20-bit number 11 bits to the left and one bit to the right.
19 0
1 1 0 0 0 1 0 0 0 1 1 1 0 1 0 0 1 0 0 1
20
31 0
1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 0 1 0 0 1 0 0 1 0
32
Figure 5.3: Sign-extending a negative 20-bit number 11 bits to the left and one bit to the right.
1449 Given the contents of the memory dump shown in Figure 5.4, m8(0x42) refers to the memory location
1450 at address 4216 that currently contains the 8-bit value fc16 .
1451 The mn (addr) notation can be used to refer to memory that is being read or written depending on
1452 the context.
~/rvalp/book/./rv32/[Link] Page 44 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.1. CONVENTIONS AND TERMINOLOGY
1453 When memory is being written, the following notation is used to indicate that the least significant 8
1454 bis of source will be is written into memory at the address addr:
1456 When memory is being read, the following notation is used to indicate that the 8 bit value at the
1457 address addr will be read and stored into dest:
00000030 2f 20 72 65 61 64 20 61 20 62 69 6e 61 72 79 20
00000040 66 69 fc 65 20 66 69 6c 6c 65 64 20 77 69 74 68
00000050 20 72 76 33 32 49 20 69 6e 73 74 72 75 63 74 69
00000060 6f 6e 73 20 61 6e 64 20 66 65 65 64 20 74 68 65
Figure 5.4: Sample memory contents.
1462 Given the contents of the memory dump shown in Figure 5.4, m16(0x42) refers to the memory location
1463 at address 4216 that currently contains 65fc16 . See also section 5.1.6.
1466 Given the contents of the memory dump shown in Figure 5.4, m32(0x42) refers to the memory location
1467 at address 4216 that currently contains 662065fc16 . See also section 5.1.6.
1470 Given the contents of the memory dump shown in Figure 5.4, m64(0x42) refers to the memory location
1471 at address 4216 that currently contains 656c6c69662065fc16 . See also section 5.1.6.
1474 Given the contents of the memory dump shown in Figure 5.4, m128(0x42) refers to the memory lo-
1475 cation at address 4216 that currently contains 7220687469772064656c6c69662065fc16 . See also sec-
1476 tion 5.1.6.
~/rvalp/book/./rv32/[Link] Page 45 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.1. CONVENTIONS AND TERMINOLOGY
1482 An address that is within [−4096..4095] of the current instruction location. These addresses are
1483 typically expressed in assembly source code by using labels. See section 5.3.6 for examples.
1485 An address that is within [−1048576..1048575] of the current instruction location. These addresses
1486 are typically expressed in assembly source code by using labels. See section 5.3.2 for an example.
1487 5.1.15 pc
1489 5.1.16 rd
1496 An immediate numeric operand. The word immediate refers to the fact that the operand is stored
1497 within an instruction.
~/rvalp/book/./rv32/[Link] Page 46 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.2. ADDRESSING MODES
1499 The value of bits from h through l of x-register rsN. For example: rs1[15:0] refers to the contents of
1500 the 16 LSBs of rs1.
1504 This document concerns itself with the RISC-V instruction formats shown in Figure 5.5.
31 12 11 7 6 0
imm[31:12] rd opcode
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 U-type
20 5 7
31 12 11 7 6 0
imm[20|10:1|11|19:12] rd opcode
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 J-type
20 5 7
31 25 24 20 19 15 14 12 11 7 6 0
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 I-type
12 5 3 5 7
31 25 24 20 19 15 14 12 11 7 6 0
31 25 24 20 19 15 14 12 11 7 6 0
imm[11:5] rs2 rs1 funct3 imm[4:0] opcode
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 S-type
7 5 5 3 5 7
31 25 24 20 19 15 14 12 11 7 6 0
imm[12|10:5] rs2 rs1 funct3 imm[4:1|11] opcode
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 B-type
7 5 5 3 5 7
1505 The method/format of the instructions has been designed with an eye on the ease of future manufacture
1506 of the machine that will execute them. It is easier to build a machine if it does not have to accommodate
1507 many different ways to perform the same task. The result is that a machine can be built with fewer
1508 gates, consumes less power, and can run faster than if it were built when a priority is on how a user
1509 might prefer to decode the same instructions from a hex dump.
1510 Observe that all instructions have their opcode in bits 0-6 and when they include an rd register it will
1511 be specified in bits 7-11, an rs1 register in bits 15-19, an rs2 register in bits 20-24, and so on. This
1512 has a seemingly strange impact on the placement of any immediate operands.
~/rvalp/book/./rv32/[Link] Page 47 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
1513 When immediate operands are present in an instruction, they are placed in the remaining unused bits.
1514 However, they are organized such that the sign bit is always in bit 31 and the remaining bits placed
1515 so as to minimize the number of places any given bit is located in different instructions.
1516 For example, consider immediate operand bits 12-19. In the U-type format they are in bit positions
1517 12-19. In the J-type format they are also in positions 12-19. In the J-type format immediate operand
1518 bits 1-10 are in the same instruction bit positions as they are in the I-type format and immediate
1519 operand bits 5-10 are in the same positions as they are in the B-type and S-type formats.
1520 While this is inconvenient for anyone looking at a memory hexdump, it does make sense when consid-
1521 ering the impact of this choice on the number of gates needed to implement circuitry to extract the
1522 immediate operands.
1524 The U-Type format is used for instructions that use a 20-bit immediate operand and an rd destination
1525 register.
1526 The rd field contains an x register number to be set to a value that depends on the instruction.
1527 If XLEN=32 then the imm value will extracted from the instruction and converted as shown in
1528 Figure 5.6 to form the imm_u value.
31 12 11 7 6 0
imm[31:12] rd opcode
a b c d e f g h i j k l mn o p q r s t 0 0 1 0 1 0 1 1 0 1 1 1 U-type
20 5 7
31 12 11 0
a b c d e f g h i j k l mn o p q r s t 0 0 0 0 0 0 0 0 0 0 0 0 imm u
20 12
1529 Notice that the 20-bits of the imm field are mapped in the same order and in the same relative position
1530 that they appear in the instruction when they are used to create the value of the immediate operand.
1531 Leaving the imm bits on the left, in the “upper bits” of the imm_u value suggests a rationale for the
1532 name of this format.
~/rvalp/book/./rv32/[Link] Page 48 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
1537 Add the address of the instruction to the imm_u value as shown Figure 5.6 and store the result
1538 in register rd.
1539 For example, if the instruction auipc x22,0x10001 is executed from memory address 0x800012f4
1540 then register x22 will be set to 0x900022f4.
1541 If XLEN=64 then the imm_u value in this example will be converted to the same two’s complement
1542 integer value by extending the sign-bit further to the left.
1544 The J-type instruction format is used to encode the jal instruction with an immediate value that
1545 determines the jump target address. It is similar to the U-type, but the bits in the immediate operand
1546 are arranged in a different order.
1547 Note that the imm_j value is a 21-bit value in the range of [−1048576..1048575] representing a pc-
1548 relative offset to the target address.
1549 If XLEN=32 then the imm value will extracted from the instruction and converted as shown in
1550 Figure 5.7 to form the imm_j value.
31 12 11 7 6 0
imm[20|10:1|11|19:12] rd opcode
a b c d e f g h i j k l mn o p q r s t 0 0 1 1 1 1 1 0 1 1 1 1 J-type
20 5 7
31 21 20 19 12 11 10 1 0
a a a a a a a a a a a a mn o p q r s t l b c d e f g h i j k 0 imm j
11 1 8 1 10 1
1551 The J-type format is used by the Jump And Link instruction that calculates the target address by
1552 adding imm_j to the current program counter. Since no instruction can be placed at an odd address the
1553 20-bit imm value is zero-extended to the right to represent a 21-bit signed offset capable of expressing
1554 a wider range of target addresses than the 20-bit imm value alone.
~/rvalp/book/./rv32/[Link] Page 49 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
1566 The instruction at address 0x10 has a target address of 0x10 and the imm_j is zero because
1567 offset from the “current instruction” to the target is zero.
1568 The instruction at address 0x14 has a target address of 0x1c and the imm_j is 0x08 because
1569 0x1c - 0x14 = 0x08.
1570 See also section 5.3.6.
31 25 24 20 19 15 14 12 11 7 6 0
1573 The R-type instructions are used for operations that set a destination register rd to the result of an
1574 arithmetic, logical or shift operation applied to source registers rs1 and rs2.
1575 Note that instruction bit 30 (part of the the funct7 field) is used to select between the add and sub
1576 instructions as well as to select between arithmetic and logical shifting.
~/rvalp/book/./rv32/[Link] Page 50 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
1625 The I-type instruction format is used to encode instructions with a signed 12-bit immediate operand
1626 with a range of [−2048..2047], an rd register, and an rs1 register.
1627 If XLEN=32 then the 12-bit imm value example will extracted from the instruction and converted as
1628 shown in Figure 5.8 to form the imm_i value.
1629 A special case of the I-type is used for shift-immediate instructions where the imm field is used to
1630 represent the number of bit positions to shift as shown in Figure 5.9. In this variation, the least
1631 significant five bits of the imm field are zero-extended to form the shamt_i value.4
1632 Note that bit 30 is used to select between arithmetic and logical shifting.
~/rvalp/book/./rv32/[Link] Page 51 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
a b c d e f g h i j k l 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 I-type
12 5 3 5 7
31 12 11 0
a a a a a a a a a a a a a a a a a a a a a b c d e f g h i j k l imm i
20 12
31 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode
0 1 0 0 0 0 0 h i j k l 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 I-type
12 5 3 5 7
31 5 4 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 h i j k l shamt i
27 5
~/rvalp/book/./rv32/[Link] Page 52 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
00002640: 6f 00 00 00 6f 00 00 00 b7 87 00 00 03 a5 07 43 *o...o..........C*
00002650: 67 80 00 00 00 00 00 00 76 61 6c 3d 00 00 00 00 *g.......val=....*
00002660: 00 00 00 00 80 84 2e 41 1f 85 45 41 80 40 9a 44 *.......A..EA.@.D*
00002670: 4f 11 f3 c3 6e 8a 67 41 20 1b 00 00 20 1b 00 00 *O...[Link] ... ...*
00002680: 44 1b 00 00 14 1b 00 00 14 1b 00 00 04 1c 00 00 *D...............*
1648 Set register rd to the value of the sign-extended byte fetched from the memory address given
1649 by the sum of rs1 and imm_i.
1650 For example, given the memory contents shown in Figure 5.10, if register x13 = 0x00002650
1651 then the instruction lb x12,1(x13) will set x12 to the value 0xffffff80.
1652 • lbu rd,imm(rs1)
1653 Set register rd to the value of the zero-extended byte fetched from the memory address given
1654 by the sum of rs1 and imm_i.
1655 For example, given the memory contents shown in Figure 5.10, if register x13 = 0x00002650
1656 then the instruction lb x12,1(x13) will set x12 to the value 0x00000080.
1657 • lh rd,imm(rs1)
1658 Set register rd to the value of the sign-extended 16-bit little-endian half-word value fetched from
1659 the memory address given by the sum of rs1 and imm_i.
1660 For example, given the memory contents shown in Figure 5.10, if register x13 = 0x00002650
1661 then the instruction lh x12,-2(x13) will set x12 to the value 0x00004307.
1662 If register x13 = 0x00002650 then the instruction lh x12,-8(x13) will set x12 to the value
1663 0xffff87b7.
1664 • lhu rd,imm(rs1)
1665 Set register rd to the value of the zero-extended 16-bit little-endian half-word value fetched from
1666 the memory address given by the sum of rs1 and imm_i.
1667 For example, given the memory contents shown in Figure 5.10, if register x13 = 0x00002650
1668 then the instruction lhu x12,-2(x13) will set x12 to the value 0x00004307.
1669 If register x13 = 0x00002650 then the instruction lhu x12,-8(x13) will set x12 to the value
1670 0x000087b7.
1671 • lw rd,imm(rs1)
1672 Set register rd to the value of the sign-extended 32-bit little-endian word value fetched from the
1673 memory address given by the sum of rs1 and imm_i.
1674 For example, given the memory contents shown in Figure 5.10, if register x13 = 0x00002650
1675 then the instruction lw x12,-4(x13) will set x12 to the value 4307a503.
1676 • ori rd,rs1,imm
1677 Set register rd to the bitwise or of rs1 and imm_i.
1678 For example, if x17 = 0x55551111 then the instruction ori x12,x17,0x0ff will set x12 to the
1679 value 0x555511ff.
1680 Recall that imm is sign-extended. Therefore if x17 = 0x55551111 then the instruction ori x12,x17,0x800
1681 will set x12 to the value 0xfffff911.
1682 • slli rd,rs1,imm
1683 Shift rs1 left by the number of bits given in shamt_i (as shown in Figure 5.9) and store the
1684 result in rd.
~/rvalp/book/./rv32/[Link] Page 53 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
1685 For example, if x17 = 0x12345678 then the instruction slli x12,x17,4 will set x12 to the
1686 value 0x23456780.
1687 • slti rd,rs1,imm
1688 If the signed integer value in rs1 is less than the signed integer value in imm_i then set rd to 1.
1689 Otherwise, set rd to 0.
1690 • sltiu rd,rs1,imm
1691 If the unsigned integer value in rs1 is less than the unsigned integer value in imm_i then set rd
1692 to 1. Otherwise, set rd to 0.
1693 Note that imm_i is always created by sign-extending the imm value as shown in Figure 5.8 even
1694 though it is then later used as an unsigned integer for the purposes of comparing its magnitude
1695 to the unsigned value in rs1. Therefore, this instruction provides a method to compare rs1 to
1696 a value in the ranges of [0..0x7ff] and [0xfffff800..0xffffffff].
1697 • srai rd,rs1,imm
1698 Arithmetic-shift rs1 right by the number of bits given in shamt_i (as shown in Figure 5.9) and
1699 store the result in rd.
1700 For example, if x17 = 0x87654321 then the instruction srai x12,x17,4 will set x12 to the
1701 value 0xf8765432.
1702 • srli rd,rs1,imm
1703 Logic-shift rs1 right by the number of bits given in shamt_i (as shown in Figure 5.9) and store
1704 the result in rd.
1705 For example, if x17 = 0x87654321 then the instruction srli x12,x17,4 will set x12 to the
1706 value 0x08765432.
1707 • xori rd,rs1,imm
1708 Set register rd to the bitwise xor of rs1 and imm_i.
1709 For example, if x17 = 0x55551111 then the instruction xori x12,x17,0x0ff will set x12 to
1710 the value 0x555511ee.
1711 Recall that imm is sign-extended. Therefore if x17 = 0x55551111 then xori x12,x17,0x800
1712 will set x12 to the value 0xaaaae911.
1714 The S-type instruction format is used to encode instructions with a signed 12-bit immediate operand
1715 with a range of [−2048..2047], an rs1 register, and an rs2 register.
1716 If XLEN=32 then the 12-bit imm value example will extracted from the instruction and converted as
1717 shown Figure 5.11 to form the imm_s value.
1718 • sb rs2,imm(rs1)
1719 Set the byte of memory at the address given by the sum of rs1 and imm_s to the 8 LSBs of rs2.
1720 For example, given the memory contents shown in Figure 5.10, if registers x13 = 0x00002650
1721 and x12 = 0x12345678 then the instruction sb x12,1(x13) will change the memory byte at
1722 address 0x00002651 from 0x80 to 0x78 resulting in:
~/rvalp/book/./rv32/[Link] Page 54 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
31 25 24 20 19 15 14 12 11 7 6 0
imm[11:5] rs2 rs1 funct3 imm[4:0] opcode
a b c d e f g 0 1 1 1 1 0 0 0 1 1 0 0 0 u v w x y 0 1 0 0 0 1 1 S-type
7 5 5 3 5 7
31 12 11 5 4 0
a a a a a a a a a a a a a a a a a a a a a b c d e f g u v w x y imm s
20 7 5
1728 • sh rs2,imm(rs1)
1729 Set the 16-bit half-word of memory at the address given by the sum of rs1 and imm_s to the 16
1730 LSBs of rs2.
1731 For example, given the memory contents shown in Figure 5.10, if registers x13 = 0x00002650
1732 and x12 = 0x12345678 then the instruction sh x12,2(x13) will change the memory half-word
1733 at address 0x00002652 from 0x0000 to 0x5678 resulting in:
1739 • sw rs2,imm(rs1)
1740 Store the 32-bit value in rs2 into the memory at the address given by the sum of rs1 and imm_s.
1741 For example, given the memory contents shown in Figure 5.10, if registers x13 = 0x00002650
1742 and x12 = 0x12345678 then the instruction sw x12,0(x13) will change the memory word at
1743 address 0x00002650 from 0x00008067 to 0x12345678 resulting in:
~/rvalp/book/./rv32/[Link] Page 55 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.3. INSTRUCTION ENCODING FORMATS
1750 The B-type instruction format is used for branch instructions that require an even immediate value
1751 that is used to determine the branch target address as an offset from the current instruction’s address.
1752 If XLEN=32 then the 12-bit imm value example will extracted from the instruction and converted as
1753 shown in Figure 5.12 to form the imm_b value.
31 25 24 20 19 15 14 12 11 7 6 0
imm[12|10:5] rs2 rs1 funct3 imm[4:1|11] opcode
a b c d e f g 0 1 1 1 1 0 0 0 1 1 0 0 0 u v w x y 1 1 0 0 0 1 1 B-type
7 5 5 3 5 7
31 13 12 11 10 5 4 1 0
a a a a a a a a a a a a a a a a a a a a y b c d e f g u v w x 0 imm b
19 1 1 6 4 1
1754 Note that imm_b is expressed in the instruction as a target address that is converted to a 13-bit value
1755 in the range of [−4096..4095] representing a pc-relative offset to the target address. For example,
1756 consider the branch instructions in the following code:
1761 The instruction at address 0x0 has a target address of zero and imm_b is zero because the offset from
1762 the “current instruction” to the target is zero.5
1763 The instruction at address 0x4 has a target address of 0xc and it has an imm_b of 0x08 because
1764 0x4 + 0x08 = 0x0c.
1765 The instruction at address 0x8 has a target address of zero and imm_b is 0xfffffff8 (-8) because
1766 0x8 + 0xfffffff8 = 0x0.
~/rvalp/book/./rv32/[Link] Page 56 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.4. CPU REGISTERS
1783 The registers are names x0 through x31 and have aliases suited to their conventional use. The following
1784 table describes each register.
1785 Note that the calling calling convention specifies that only some of the registers are to be saved by ý Fix Me:
1786 functions if they alter their contents. The idea being that accessing memory is time-consuming and Need to add a section that
discusses the calling
1787 that by classifying some registers as “temporary” (not saved by any function that alter its contents) conventions
1788 it is possible to carefully implement a function with less need to store register values on the stack in
1789 order to use them to perform the operations of the function.
1790 The lack of grouping the temporary and saved registers is due to the fact that the C extension provides
1791 access to only the first 16 registers when executing instructions in the compressed format.
1795 All instructions must be naturally aligned to their 4-byte boundaries. [1, p. 5]
~/rvalp/book/./rv32/[Link] Page 57 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
5.5. MEMORY
1796 If a RISC-V processor implements the C (compressed) extension then instructions may be aligned to
1797 2-byte boundaries.[1, p. 68]
1798 Data alignment is not necessary but unaligned data can be inefficient. Accessing unaligned data using
1799 any of the load or store instructions can also prevent a memory access from operating atomically. [1,
1800 p.19] See also ??.
~/rvalp/book/./[Link] Page 58 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1801 Appendix A
1803 All of the software presented in this text was assembled using the GNU toolchain and executed using
1804 the rvddt simulator on a Linux (Ubuntu 18.04 LTS) operating system.
1805 The installation instructions provided here were tested on a clean OS install on June 9, 2018.
1807 In order to install custom code in a location that will not cause interference with other applications ý Fix Me:
1808 (and allow for easy hacking and cleanup), these will install the toolchain under a private directory: It would be good to find
some Mac and Windows
1809 ~/projects/riscv/install. At any time you can remove everything and start over by executing the users to write and test
1810 following command: proper variations on this
section to address those
1811
systems. Pull requests,
1812 1 rm - rf ~/ projects / riscv / install
1813 welcome!
Be very careful how you type the above rm command. If typed incorrectly, it could irreversibly
remove many of your files!
1814
1815 Before building the toolchain, a number of utilities must be present on your system. The following
1816 will install those that are needed:
1817
1818 1 sudo apt install autoconf automake autotools - dev curl libmpc - dev \
1819 2 libmpfr - dev libgmp - dev gawk build - essential bison flex texinfo gperf \
1820
1821
3 libtool patchutils bc zlib1g - dev libexpat - dev
1822 Note that the above apt command is the only operation that should be performed as root. All other
1823 commands should be executed as a regular user. This will eliminate the possibility of clobbering
1824 system files that should not be touched when tinkering with the toolchain applications.
~/rvalp/book/./install/[Link] Page 59 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
A.2. RVDDT
1832 6 ./ configure -- prefix = $INS_DIR -- with - arch = rv32i -- with - abi = ilp32
1833
1834
7 make
1835 After building the toolchain, make it available by putting it into your PATH by adding the following
1836 to the end of your .bashrc file:
1837
1838
1839
1 export PATH = $PATH :~/ projects / riscv / install / rv32i / bin
1840 For this PATH change to take place, start a new terminal or paste the same export command into
1841 your existing terminal.
1843 Download and install the rvddt simulator by executing the following commands. Building the rvddt
1844 example programs will verify that the GNU toolchain has been built and installed properly.
1845
1846 1 cd ~/ projects / riscv
1847 2 git clone https :// github . com / johnwinans / rvddt . git
1848 3 cd rvddt / src
1849 4 make world
1850 5 cd ../ examples
1851
1852
6 make world
1853 After building rvddt, make it available by putting it into your PATH by adding the following to the
1854 end of your .bashrc file:
1855
1856
1857
1 export PATH = $PATH :~/ projects / riscv / rvddt / src
1858 For this PATH change to take place, start a new terminal or paste the same export command into
1859 your existing terminal.
~/rvalp/book/./[Link] Page 60 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
1879 Appendix B
1882 This section provides an overview of the IEEE-754 32-bit binary floating point format.[15]
1883 • Recall that the place values for integer binary numbers are:
1885 • We can extend this to the right in binary similar to the way we do for decimal numbers:
1886 ... 128 64 32 16 8 4 2 1 . 1/2 1/4 1/8 1/16 1/32 1/64 1/128 ...
1887 The ‘.’ in a binary number is a binary point, not a decimal point.
1888 • We use scientific notation as in 2.7 × 10−47 to express either small fractions or large numbers
1889 when we are not concerned every last digit needed to represent the entire, exact, value of a
1890 number.
1891 • The format of a number in scientific notation is mantissa × baseexponent
1892 • In binary we have mantissa × 2exponent
1893 • IEEE-754 format requires binary numbers to be normalized to [Link] icand × 2exponent where
1894 the significand is the portion of the mantissa that is to the right of the binary-point.
1897 • We need not store the ‘1.’ part because all normalized floating point numbers will start that
1898 way. Thus we can save memory when storing normalized values by inserting a ‘1.’ to the left of
1899 significand.
31 30 23 22 0
1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900
sign exponent significand
1901 • −((1 + 1
4 + 1
16 ) × 2
128−127
) = −((1 + 1
4 + 1 1
16 ) × 2 ) = −(2 + 1
2 + 18 ) = −(2 + .5 + .125) = −2.625
~/rvalp/book/./float/[Link] Page 61 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
B.1. IEEE-754 FLOATING POINT NUMBER REPRESENTATION
1927 Due to the finite number of bits used to store the value of a floating point number, it is not possible to
1928 represent every one of the infinite values on the real number line. The following C programs illustrate
1929 this point.
1931 Just like the integer numbers, the powers of two that have bits to represent them can be represented
1932 perfectly. . . as can their sums (provided that the significand requires no more than 23 bits.)
~/rvalp/book/./powersoftwo.c Page 62 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
B.1. IEEE-754 FLOATING POINT NUMBER REPRESENTATION
1937 4
1938 5 union floatbin
1939 6 {
1940 7 unsigned int i;
1941 8 float f;
1942 9 };
1943 10 int main ()
1944 11 {
1945 12 union floatbin x ;
1946 13 union floatbin y ;
1947 14 int i;
1948 15 x . f = 1.0;
1949 16 while ( x . f > 1.0/1024.0)
1950 17 {
1951 18 y . f = -x . f ;
1952 19 printf ( " %25.10 f = %08 x %25.10 f = %08 x \ n " , x .f , x .i , y .f , y . i ) ;
1953 20 x . f = x . f /2.0;
1954 21 }
1955
1956
22 }
1970 When dealing with decimal values, you will find that they don’t map simply into binary floating point
1971 values.
1972 Note how the decimal numbers are not accurately represented as they get larger. The decimal number
1973 on line 10 of Listing B.4 can be perfectly represented in IEEE format. However, a problem arises in
1974 the 11Th loop iteration. It is due to the fact that the binary number can not be represented accurately
1975 in IEEE format. Its least significant bits were truncated in a best-effort attempt at rounding the value
1976 off in order to fit the value into the bits provided. This is an example of low order truncation. Once
1977 this happens, the value of x.f is no longer as precise as it could be given more bits in which to save
1978 its value.
Listing B.3: cleandecimal.c
Print Clean Decimal Numbers
1979
1980 1 # include < stdio .h >
1981 2 # include < stdlib .h >
1982 3 # include < unistd .h >
1983 4
1984 5 union floatbin
1985 6 {
1986 7 unsigned int i;
1987 8 float f;
1988 9 };
1989 10 int main ()
1990 11 {
1991 12 union floatbin x, y;
~/rvalp/book/./cleandecimal.c Page 63 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
B.1. IEEE-754 FLOATING POINT NUMBER REPRESENTATION
1992 13 int i;
1993 14
1994 15 x . f = 10;
1995 16 while ( x . f <= 1 0 0 0 0 0 0 0 0 0 0 0 0 0 . 0 )
1996 17 {
1997 18 y . f = -x . f ;
1998 19 printf ( " %25.10 f = %08 x %25.10 f = %08 x \ n " , x .f , x .i , y .f , y . i ) ;
1999 20 x . f = x . f *10.0;
2000 21 }
2001
2002
22 }
2019 These rounding errors can be exaggerated when the number we multiply the x.f value by is, itself,
2020 something that can not be accurately represented in IEEE form.1 ý Fix Me:
In a lecture one would show
1 that one tenth is a repeating
2021 For example, if we multiply our x.f value by 10 each time, we can never be accurate and we start non-terminating binary
2022 accumulating errors immediately. number that gets truncated.
This discussion should be
reproduced here in text form.
Listing B.5: erroraccumulation.c
Accumulation of Error
2023
2024 1 # include < stdio .h >
2025 2 # include < stdlib .h >
2026 3 # include < unistd .h >
2027 4
2028 5 union floatbin
2029 6 {
2030 7 unsigned int i;
2031 8 float f;
2032 9 };
2033 10 int main ()
2034 11 {
2035 12 union floatbin x, y;
2036 13 int i;
2037 14
2038 15 x . f = .1;
2039 16 while ( x . f <= 2.0)
2040 17 {
2041 18 y . f = -x . f ;
2042 19 printf ( " %25.10 f = %08 x %25.10 f = %08 x \ n " , x .f , x .i , y .f , y . i ) ;
2043 20 x . f += .1;
2044 21 }
1 Applications requiring accurate decimal values, such as financial accounting systems, can use a packed-decimal
numeric format to avoid unexpected oddities caused by the use of binary numbers.
~/rvalp/book/./float/[Link] Page 64 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
B.1. IEEE-754 FLOATING POINT NUMBER REPRESENTATION
2045
2046
22 }
2069 In order to use floating point numbers in a program without causing excessive rounding problems an
2070 algorithm can be redesigned such that the accumulation is eliminated. This example is similar to
2071 the previous one, but this time we recalculate the desired value from a known-accurate integer value.
2072 Some rounding errors remain present, but they can not accumulate.
Listing B.7: errorcompensation.c
Accumulation of Error
2073
2074 1 # include < stdio .h >
2075 2 # include < stdlib .h >
2076 3 # include < unistd .h >
2077 4
2078 5 union floatbin
2079 6 {
2080 7 unsigned int i;
2081 8 float f;
2082 9 };
2083 10 int main ()
2084 11 {
2085 12 union floatbin x, y;
2086 13 int i;
2087 14
2088 15 i = 1;
2089 16 while ( i <= 20)
2090 17 {
2091 18 x . f = i /10.0;
2092 19 y . f = -x . f ;
2093 20 printf ( " %25.10 f = %08 x %25.10 f = %08 x \ n " , x .f , x .i , y .f , y . i ) ;
2094 21 i ++;
2095 22 }
2096 23 return (0) ;
2097
2098
24 }
~/rvalp/book/./[Link] Page 65 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
B.1. IEEE-754 FLOATING POINT NUMBER REPRESENTATION
2099
2100 1 0.1000000015 = 3 dcccccd -0.1000000015 = bdcccccd
2101 2 0.2000000030 = 3 e4ccccd -0.2000000030 = be4ccccd
2102 3 0.3000000119 = 3 e99999a -0.3000000119 = be99999a
2103 4 0.4000000060 = 3 ecccccd -0.4000000060 = becccccd
2104 5 0.5000000000 = 3 f000000 -0.5000000000 = bf000000
2105 6 0.6000000238 = 3 f19999a -0.6000000238 = bf19999a
2106 7 0.6999999881 = 3 f333333 -0.6999999881 = bf333333
2107 8 0.8000000119 = 3 f4ccccd -0.8000000119 = bf4ccccd
2108 9 0.8999999762 = 3 f666666 -0.8999999762 = bf666666
2109 10 1.0000000000 = 3 f800000 -1.0000000000 = bf800000
2110 11 1.1000000238 = 3 f8ccccd -1.1000000238 = bf8ccccd
2111 12 1.2000000477 = 3 f99999a -1.2000000477 = bf99999a
2112 13 1.2999999523 = 3 fa66666 -1.2999999523 = bfa66666
2113 14 1.3999999762 = 3 fb33333 -1.3999999762 = bfb33333
2114 15 1.5000000000 = 3 fc00000 -1.5000000000 = bfc00000
2115 16 1.6000000238 = 3 fcccccd -1.6000000238 = bfcccccd
2116 17 1.7000000477 = 3 fd9999a -1.7000000477 = bfd9999a
2117 18 1.7999999523 = 3 fe66666 -1.7999999523 = bfe66666
2118 19 1.8999999762 = 3 ff33333 -1.8999999762 = bff33333
2119
2120
20 2.0000000000 = 40000000 -2.0000000000 = c0000000
~/rvalp/book/./[Link] Page 66 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2121 Appendix C
2125 ascii - ASCII character set encoded in octal, decimal, and hexadecimal
2127 ASCII is the American Standard Code for Information Interchange. It is a 7-bit code. Many 8-bit
2128 codes (e.g., ISO 8859-1) contain ASCII as their lower half. The international counterpart of ASCII is
2129 known as ISO 646-IRV.
~/rvalp/book/./ascii/[Link] Page 67 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
C.2. DESCRIPTION
~/rvalp/book/./ascii/[Link] Page 68 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
C.3. NOTES
2199 For convenience, below are more compact tables in hex and decimal.
2221 On older terminals, the underscore code is displayed as a left arrow, called backarrow, the caret is
2222 displayed as an up-arrow and the vertical bar has a hole in the middle.
2223 Uppercase and lowercase characters differ by just one bit and the ASCII character 2 differs from the
2224 double quote by just one bit, too. That made it much easier to encode characters mechanically or
2225 with a non-microcontroller-based electronic keyboard and that pairing was found on old teletypes.
2226 The ASCII standard was published by the United States of America Standards Institute (USASI) in
2227 1968.
2229 This page is part of release 4.04 of the Linux man-pages project. A description of the project,
2230 information about reporting bugs, and the latest version of this page, can be found at [Link]
2231 [Link]/doc/man-pages/.
~/rvalp/book/./[Link] Page 69 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2232 Appendix D
2234 Creative Commons Corporation (”Creative Commons”) is not a law firm and does not provide legal services or legal advice.
2235 Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons
2236 makes its licenses and related information available on an ”as-is” basis. Creative Commons gives no warranties regarding its
2237 licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all
2238 liability for damages resulting from their use to the fullest extent possible.
2244 Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use
2245 material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read
2246 and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights
2247 necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any
2248 material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation
2249 to copyright. More considerations for licensors: [Link]
2250 Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the li-
2251 censed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason-for ex-
2252 ample, because of any applicable exception or limitation to copyright-then that use is not regulated by the license. Our
2253 licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the
2254 licensed material may still be restricted for other reasons, including because others have copyright or other rights in the
2255 material. A licensor may make special requests, such as asking that all changes be marked or described. Although not re-
2256 quired by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public:
2257 [Link]
2258
2271 b. Adapter’s License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted
~/rvalp/book/./license/[Link] Page 70 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2272 Material in accordance with the terms and conditions of this Public License.
2273 c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without
2274 limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the
2275 rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not
2276 Copyright and Similar Rights.
2277 d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented
2278 under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or
2279 similar international agreements.
2280 e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and
2281 Similar Rights that applies to Your use of the Licensed Material.
2282 f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this
2283 Public License.
2284 g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are
2285 limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has
2286 authority to license.
2287 h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
2288 i. Share means to provide material to the public by any means or process that requires permission under the Licensed
2289 Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or im-
2290 portation, and to make material available to the public including in ways that members of the public may access the
2291 material from a place and at a time individually chosen by them.
2292 j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European
2293 Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as
2294 well as other essentially equivalent rights anywhere in the world.
2295 k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding
2296 meaning.
2299 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-
2300 free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material
2301 to:
2302 a. reproduce and Share the Licensed Material, in whole or in part; and
2303 b. produce, reproduce, and Share Adapted Material.
2304 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use,
2305 this Public License does not apply, and You do not need to comply with its terms and conditions.
2306 3. Term. The term of this Public License is specified in Section 6(a).
2307 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights
2308 in all media and formats whether now known or hereafter created, and to make technical modifications necessary
2309 to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making
2310 technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to
2311 circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications
2312 authorized by this Section 2(a) (4) never produces Adapted Material.
2313 5. Downstream recipients.
2314 a. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives
2315 an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public
2316 License.
2317 b. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on,
2318 or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the
2319 Licensed Rights by any recipient of the Licensed Material.
2320 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply
2321 that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted
2322 official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
2324 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy,
2325 and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to
2326 assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed
2327 Rights, but not otherwise.
2328 2. Patent and trademark rights are not licensed under this Public License.
2329 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed
2330 Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory
2331 licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
~/rvalp/book/./license/[Link] Page 71 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2332 Section 3. License Conditions
2333 Your exercise of the Licensed Rights is expressly made subject to the following conditions.
2334 a. Attribution.
2335 1. If You Share the Licensed Material (including in modified form), You must:
2336 a. retain the following if it is supplied by the Licensor with the Licensed Material:
2337 i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution,
2338 in any reasonable manner requested by the Licensor (including by pseudonym if designated);
2339 ii. a copyright notice;
2340 iii. a notice that refers to this Public License;
2341 iv. a notice that refers to the disclaimer of warranties;
2342 v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
2343 b. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
2344 c. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or
2345 hyperlink to, this Public License.
2346 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and
2347 context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions
2348 by providing a URI or hyperlink to a resource that includes the required information.
2349 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent
2350 reasonably practicable.
2351 4. If You Share Adapted Material You produce, the Adapter’s License You apply must not prevent recipients of the
2352 Adapted Material from complying with this Public License.
2355 a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial
2356 portion of the contents of the database;
2357 b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database
2358 Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted
2359 Material; and
2360 c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the
2361 database.
2362 For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where
2363 the Licensed Rights include other Copyright and Similar Rights.
2373 b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL
2374 THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPE-
2375 CIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS,
2376 EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL,
2377 EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES,
2378 OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMI-
2379 TATION MAY NOT APPLY TO YOU.
2380 c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the
2381 extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
~/rvalp/book/./license/[Link] Page 72 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2382 Section 6. Term and Termination
2383 a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to
2384 comply with this Public License, then Your rights under this Public License terminate automatically.
2385 b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
2386 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the
2387 violation; or
2388 2. upon express reinstatement by the Licensor.
2389 For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your
2390 violations of this Public License.
2391 c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or
2392 stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
2397 b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from
2398 and independent of the terms and conditions of this Public License.
2403 b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed
2404 to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from
2405 this Public License without affecting the enforceability of the remaining terms and conditions.
2406 c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed
2407 to by the Licensor.
2408 d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and
2409 immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
2410
2411 Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of
2412 its public licenses to material it publishes and in those instances will be considered the Licensor. The text of the Creative
2413 Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited
2414 purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the
2415 Creative Commons policies published at [Link] Creative Commons does not authorize the use
2416 of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent
2417 including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other
2418 arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph
2419 does not form part of the public licenses.
~/rvalp/book/./[Link] Page 73 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2421 Bibliography
2422 [1] RISC-V Foundation, The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Document
2423 Version 2.2, 5 2017. Editors Andrew Waterman and Krste Asanović. iv, 3, 4, 16, 25, 27, 32, 57,
2424 58, 80
2425 [2] D. Patterson and A. Waterman, The RISC-V Reader: An Open Architecture Atlas. Strawberry
2426 Canyon, 11 2017. ISBN: 978-0999249116. iv
2427 [3] D. Patterson and J. Hennessy, Computer Organization and Design RISC-V Edition: The Hard-
2428 ware Software Interface. Morgan Kaufmann, 4 2017. ISBN: 978-0128122754. iv, 27
2429 [4] W. F. Decker, “A modern approach to teaching computer organization and assembly language
2430 programming,” SIGCSE Bull., vol. 17, pp. 38–44, 12 1985. iv
2431 [5] Texas Instruments, SN54190, SN54191, SN54LS190, SN54LS191, SN74190, SN74191,
2432 SN74LS190, SN74LS191 Synchronous Up/Down Counters With Down/Up Mode Control, 3 1988.
2433 iv
2434 [6] Texas Instruments, SN54154, SN74154 4–line to 16–line Decoders/Demultiplexers, 12 1972. iv
2435 [7] Intel, MCS-85 User’s Manual, 9 1978. iv
2436 [8] Radio Shack, TRS-80 Editor/Assembler Operation and Reference Manual, 1978. iv
2437 [9] Motorola, MC68000 16–bit Microprocessor User’s Manual, 2nd ed., 1 1980. MC68000UM(AD2).
2438 iv
2439 [10] R. A. Overbeek and W. E. Singletary, Assembler Language With ASSIST. Science Research
2440 Associates, Inc., 2nd ed., 1983. iv
2441 [11] IBM, IBM System/370 Principals of Operation, 7th ed., 3 1980. iv
2442 [12] IBM, OS/VS-DOS/VSE-VM/370 Assembler Language, 6th ed., 3 1979. iv
2449 [15] “Ieee standard for floating-point arithmetic,” IEEE Std 754-2019 (Revision of IEEE 754-2008),
2450 pp. 1–84, 2019. 61, 62
2451 [16] RISC-V Foundation, The RISC-V Instruction Set Manual, Volume II: Privileged Architecture,
2452 Document Version 1.10, 5 2017. Editors Andrew Waterman and Krste Asanović.
~/rvalp/book/./[Link] Page 74 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
BIBLIOGRAPHY
2453 [17] P. Dabbelt, S. O’Rear, K. Cheng, A. Waterman, M. Clark, A. Bradbury, D. Horner, M. Nordlund,
2454 and K. Merker, RISC-V ELF psABI specification, 2017.
2455 [18] R. M. Stallman and the GCC Developer Community, Using the GNU Compiler Collection (For
2456 GCC version 7.3.0). Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2457 02110-1301 USA: GNU Press, 2017.
2459
~/rvalp/book/./[Link] Page 75 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2460 Glossary
2461 address A numeric value used to uniquely identify each byte of main memory. 2, 75
2462 alignment Refers to a range of numeric values that begin at a multiple of some number. Primarily
2463 used when referring to a memory address. For example an alignment of two refers to one or
2464 more addresses starting at even address and continuing onto subsequent adjacent, increasing
2465 memory addresses. 26, 75
2466 ASCII American Standard Code for Information Interchange. See Appendix C. 21, 75
2467 big-endian A number format where the most significant values are printed to the left of the lesser
2468 significant values. This is the method that everyone uses to write decimal numbers every day.
2469 23, 30, 31, 75, 77
2470 binary Something that has two parts or states. In computing these two states are represented by
2471 the numbers one and zero or by the conditions true and false and can be stored in one bit. 1, 3,
2472 75, 76, 77
2473 bit One binary digit. 3, 6, 10, 75, 76, 77
2474 byte A binary value represented by 8 bits. 2, 6, 75, 76, 77
2477 exception An error encountered by the CPU while executing an instruction that can not be com-
2478 pleted. 27, 75
~/rvalp/book/./[Link] Page 76 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
Glossary
2488 little-endian A number format where the least significant values are printed to the left of the more
2489 significant values. This is the opposite ordering that everyone learns in grade school when
2490 learning how to count. For example, the big-endian number written as “1234” would be written
2491 in little endian form as “4321”. 24, 75
2492 low order bits Some number of LSBs. 75
2493 LSB Least Significant Bit. 10, 12, 22, 43, 47, 52, 54, 55, 75, 77
2494 machine language The instructions that are executed by a CPU that are expressed in the form of
2495 binary values. 1, 75
2496 mnemonic A method used to remember something. In the case of assembly language, each machine
2497 instruction is given a name so the programmer need not memorize the binary values of each
2498 machine instruction. 1, 75
2499 MSB Most Significant Bit. 10, 12, 13, 19, 20, 22, 43, 44, 75, 76
2500 nybble Half of a byte is a nybble (sometimes spelled nibble.) Another word for hit. 10, 75
2501 overflow The situation where the result of an addition or subtraction operation is approaching pos-
2502 itive or negative infinity and exceeds the number of bits allotted to contain the result. This is
2503 typically caused by high-order truncation. 62, 75
2504 place value the numerical value that a digit has as a result of its position within a number. For
2505 example, the digit 2 in the decimal number 123 is in the ten’s place and its place value is 20. 9,
2506 10, 11, 23, 24, 75
2507 program A ordered list of one or more instructions. 1, 75
2516 thread An stream of instructions. When plural, it is used to refer to the ability of a CPU to execute
2517 multiple instruction streams at the same time. 3, 75
2518 underflow The situation where the result of an addition or subtraction operation is approaching
2519 zero and exceeds the number of bits allotted to contain the result. This is typically caused by
2520 low-order truncation. 62, 75
2521 XLEN The number of bits a RISC-V x integer register (such as x0). For RV32 XLEN=32, RV64
2522 XLEN=64 and so on. 48, 49, 51, 54, 56, 75, 77
~/rvalp/book/./[Link] Page 77 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
Index
2552 L
2553 Least significant bit, 10
2554 little-endian, 24
2555 LSB, see Least significant bit
2556 M
2557 Most significant bit, 10
2558 MSB, see Most significant bit
2559 O
2560 objdump, 34
2561 overflow, 15
~/rvalp/book/./[Link] Page 78 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2581 RV32I Reference Card
~/rvalp/book/./refcard/[Link] Page 79 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600
2584 RV32I Base Instruction Set Encoding [1, p. 104]
31 25 24 20 19 15 14 12 11 7 6 0
~/rvalp/book/./[Link] Page 80 of 80
v0.12-0-g5df1fff 2021-03-03 07:58:24 -0600