Download as pdf or txt
Download as pdf or txt
You are on page 1of 67

RISC-V Assembly Language

Programming Stephen Smith


Visit to download the full and correct content document:
https://ebookmass.com/product/risc-v-assembly-language-programming-stephen-smit
h/
Maker Innovations Series

Jump start your path to discovery with the Apress Maker Innovations
series! From the basics of electricity and components through to the
most advanced options in robotics and Machine Learning, you’ll forge a
path to building ingenious hardware and controlling it with cutting-
edge software. All while gaining new skills and experience with
common toolsets you can take to new projects or even into a whole new
career.
The Apress Maker Innovations series offers projects-based learning,
while keeping theory and best processes front and center. So you get
hands-on experience while also learning the terms of the trade and how
entrepreneurs, inventors, and engineers think through creating and
executing hardware projects. You can learn to design circuits, program
AI, create IoT systems for your home or even city, and so much more!
Whether you’re a beginning hobbyist or a seasoned entrepreneur
working out of your basement or garage, you’ll scale up your skillset to
become a hardware design and engineering pro. And often using low-
cost and open-source software such as the Raspberry Pi, Arduino, PIC
microcontroller, and Robot Operating System (ROS). Programmers and
software engineers have great opportunities to learn, too, as many
projects and control environments are based in popular languages and
operating systems, such as Python and Linux.
If you want to build a robot, set up a smart home, tackle assembling
a weather-ready meteorology system, or create a brand-new circuit
using breadboards and circuit design software, this series has all that
and more! Written by creative and seasoned Makers, every book in the
series tackles both tested and leading-edge approaches and
technologies for bringing your visions and projects to life.
More information about this series at
https://link.springer.com/bookseries/17311.
Stephen Smith

RISC-V Assembly Language


Programmierung
Unlock the Power of the RISC-V Instruction Set
Stephen Smith
Gibsons, BC, Canada

ISSN 2948-2542 e-ISSN 2948-2550


Maker Innovations Series
ISBN 979-8-8688-0136-5 e-ISBN 979-8-8688-0137-2
https://doi.org/10.1007/979-8-8688-0137-2

© Stephen Smith 2024

This work is subject to copyright. All rights are solely and exclusively
licensed by the Publisher, whether the whole or part of the material is
concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in
any other physical way, and transmission or information storage and
retrieval, electronic adaptation, computer software, or by similar or
dissimilar methodology now known or hereafter developed.

The use of general descriptive names, registered names, trademarks,


service marks, etc. in this publication does not imply, even in the
absence of a specific statement, that such names are exempt from the
relevant protective laws and regulations and therefore free for general
use.

The publisher, the authors, and the editors are safe to assume that the
advice and information in this book are believed to be true and accurate
at the date of publication. Neither the publisher nor the authors or the
editors give a warranty, expressed or implied, with respect to the
material contained herein or for any errors or omissions that may have
been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
This Apress imprint is published by the registered company APress
Media, LLC, part of Springer Nature.
The registered company address is: 1 New York Plaza, New York, NY
10004, U.S.A.
This book is dedicated to my beloved wife and editor Cathalynn Labonté-
Smith.
Introduction
The heart of every computer and smart device is a Central Processing
Unit (CPU). Historically, each CPU has been produced by a single
company which tightly controls the instruction set and internal
workings of the CPU. RISC-V (pronounced Risk Five) is a new approach
based on open-source principles. Anyone can implement a RISC-V CPU
using a standardized instruction set without requiring any special
licensing or royalty payments. As a result, RISC-V CPUs can be at a
much lower cost than proprietary CPUs and have exploded in the low-
cost microcontroller space. Now that more powerful RISC-V CPUs are
appearing, leading to Single Board Computers (SBCs) similar to the
Raspberry Pi, along with inexpensive low-end laptops and tablets, this
book presents the inner workings of typical RISC-V CPUs and details
the open-source Assembly Language instruction set they all implement.
Assembly Language is the native, lowest level way to program a
computer. Each processing chip has its own Assembly Language. This
book teaches programming RISC-V CPUs either running 32- or 64-bits.
Learning how a computer works, and mastering Assembly
Language, is an excellent way to get into the nitty-gritty details. These
low-cost microcontrollers and SBCs provide ideal platforms to learn
advanced concepts in computing.
Even though all of these devices are low-powered and compact,
they’re still sophisticated computers, many of which are capable of
running the full Linux operating system. Due to the RISC-V instruction
set standard, learning to program on one RISC-V processor is directly
applicable to all RISC-V processors.
In this book, we cover how to program RISC-V processors at the
lowest level, operating as close to the hardware as possible. Readers
will learn the following:
How to format instructions and combine them into programs, as well
as details of the operative binary data formats
How to program RISC-V instruction set extensions, such as floating-
point instructions
How to control integrated hardware devices by reading and writing
to the hardware control registers directly
How to interact with the Linux operating system and microcontroller
SDKs
The simplest way to learn these tasks is with a RISC-V SBC such as
the Starfive Visionfive 2. The book also details how to emulate the RISC-
V CPU on an Intel/AMD computer using the QEMU emulator, as well as
how to program the Espressif ESP32-C3 microcontroller. All the tools
needed to learn Assembly Language programming are open source and
readily available.
This book contains many working programs to play with, use as a
starting point, or study. The only way to learn programming is by doing
it, so do not be afraid to experiment, as it is the only way to learn.
Even if Assembly Language programming isn’t used in your day-to-
day life, knowing how the processor works at the Assembly Language
level and knowing the low-level binary data structures will make you a
better programmer in all other areas. Knowing how the processor
works will let you write more efficient C code and can even help with
Python programming.
Enjoy this introduction to Assembly Language. Learning it for one
processor family helps with learning and using any other processor
architectures encountered throughout a programmer’s career.
Any source code or other supplementary material referenced by the
author in this book is available to readers on GitHub
(https://github.com/Apress). For more detailed information, please
visit https://www.apress.com/gp/services/source-code.
Acknowledgments
No book is ever written in isolation. I want to especially thank my wife
Cathalynn Labonté-Smith for her support, encouragement, and expert
editing.
I want to thank all the good folks at Apress who made the whole
process easy and enjoyable. A special shout-out to Nirmal Selvaraj, my
production editor, who kept the whole project moving quickly and
smoothly. Thanks to Miriam Haidara, the acquisitions editor, for mobile
tech and maker programs, who got the project started. Thanks to
Stewart Watkiss, my technical reviewer, who helped make this a far
better book.
Table of Contents
Chapter 1:​Getting Started
History and Evolution of the RISC-V CPU
What You Will Learn
Ten Reasons to Learn Assembly Language Programming
Running Programs on RISC-V Systems
Coding a Simple “Hello World” Program
Hello World on the Starfive Visionfive 2
Programming Hello World in the QEMU Emulator
About Hello World on the ESP32-C3 Microcontroller
Summary
Exercises
Chapter 2:​Loading and Adding
Computers and Numbers
Negative Numbers
About Two’s Complement
RISC-V Assembly Instructions
CPU Registers
RISC-V Instruction Format
About the GCC Assembler
Adding Registers
32-bits in a 64-bit World
Moving Registers
About Pseudoinstructio​ns
About Immediate Values
Loading the Top
Shifting the Bits
Loading Larger Numbers into Registers
More Shift Instructions
About Subtraction
Summary
Exercises
Chapter 3:​Tooling Up
GNU Make
Rebuild a Project
Rule for Building .​S files
Define Variables
Build with CMake
Debugging with GDB
Preparation to Debug
Setup for Linux
Set Up gdb for the ESP32-C3
Debugging with GDB
Summary
Exercises
Chapter 4:​Controlling Program Flow
Creating Unconditional Jumps
Understanding Conditional Branches
Using Branch Pseudoinstructio​ns
Constructing Loops
Create FOR Loops
Code While Loops
Coding If/​Then/​Else
Manipulating Logical Operators
Using AND
Using XOR
Using OR
Adopting Design Patterns
Converting Integers to ASCII
Using Expressions in Immediate Constants
Storing a Register to Memory
Why Not Print in Decimal?​
Performance of Branch Instructions
Using Comparison Instructions
Summary
Exercises
Chapter 5:​Thanks for the Memories
Defining Memory Contents
Aligning Data
About Program Sections
Big vs.​Little Endian
Pros of Little Endian
About Memory Addresses
Loading a Register with an Address
PC Relative Addressing
Loading Data from Memory
Combining Loading Addresses and Memory
Storing a Register
Optimizing Through Relaxing
Converting to Uppercase
Summary
Exercises
Chapter 6:​Functions and the Stack
About Stacks
Jump and Link
Nesting Function Calls
Function Parameters and Return Values
Managing the Registers
Summary of the Function Call Algorithm
Uppercase Revisited
Stack Frames
Stack Frame Example
Macros
Include Directive
Macro Definition
Labels
Why Macros?​
Using Macros to Improve Code
Summary
Exercises
Chapter 7:​Linux Operating System Services
So Many Services
Calling Convention
Finding Linux System Call Numbers
Return Codes
Structures
About Wrappers
Converting a File to Uppercase
Building .​S Files
Opening a File
Error Checking
Looping
Summary
Exercises
Chapter 8:​Programming GPIO Pins
GPIO Overview
In Linux, Everything is a File
Flashing LEDs
Moving Closer to the Metal
Virtual Memory
In Devices, Everything is Memory
Registers in Bits
GPIO Enable Registers
GPIO Output Set Registers
More Flashing LEDs
GPIOTurnOn in Detail
Root Access
Summary
Exercises
Chapter 9:​Interacting with C and Python
Calling C Routines
Printing Debug Information
Register Masking Revisited
Calling Assembly Routines from C
Packaging the Code
Static Library
Shared Library
Embedding Assembly Language Code inside C Code
Calling Assembly from Python
Summary
Exercises
Chapter 10:​Multiply and Divide
Multiplication
Examples
Division
Division by Zero and Overflow
Example
Example:​Matrix Multiplication
Vectors and Matrices
Multiplying 3x3 Integer Matrices
Summary
Exercises
Chapter 11:​Floating-Point Operations
About Floating Point Numbers
About Normalization and NaNs
Recognizing Rounding Errors
Defining Floating Point Numbers
About Floating Point Registers
The Status and Control Register
Defining the Function Call Protocol
Loading and Saving FPU Registers
Performing Basic Arithmetic
Calculating Distance Between Points
Performing Floating-Point Conversions
Floating-Point Sign Injection
Comparing Floating-Point Numbers
Example
Summary
Exercises
Chapter 12:​Optimizing Code
Optimizing the Uppercase Routine
Simplifying the Range Comparison
Restricting the Problem Domain
Tips for Optimizing Code
Avoiding Branch Instructions
Moving Code Out of Loops
Avoiding Expensive Instructions
Use Macros
Loop Unrolling
Delay Preserving Registers in Functions
Keeping Data Small
Beware of Overheating
Summary
Exercises
Chapter 13:​Reading and Understanding Code
Browsing Linux &​GCC Code
Comparing Strings
Code Created by GCC
Reverse Engineering and Ghidra
Summary
Exercises
Chapter 14:​Hacking Code
Buffer Overrun Hack
Causes of Buffer Overrun
Stealing Credit Card Numbers
Stepping Through the Stack
Mitigating Buffer Overrun Vulnerabilities
Do Not Use strcpy
PIE Is Good
Poor Stack Canaries Are the First to Go
Preventing Code Running on the Stack
Tradeoffs of Buffer Overflow Mitigation Techniques
Summary
Exercises
Appendix A:​The RISC-V Instruction Set
Appendix B:​Binary Formats
Appendix C:​Assembler Directives
Appendix D:​ASCII Character Set
Appendix E:​Answers to Exercises
Index
About the Author
Stephen Smith
is a software architect, located in
Gibsons, BC, Canada. He’s been
developing software since high school, or
way too many years to record. He is an
expert in Artificial Intelligence and
Assembly Language programming,
earned his Advanced HAM Radio License,
and enjoys mountain biking, hiking, and
nature photography. He volunteers for
Sunshine Coast Search and Rescue. He is
the author of Raspberry Pi Assembly
Language Programming: ARM Processor
Coding, Programming with 64-Bit ARM
Assembly Language: Single Board
Computer Development for Raspberry Pi
and Mobile Devices, and RP2040 Assembly
Language Programming: ARM Cortex-M0+ on the Raspberry Pi Pico, all
published by Apress. Also, he writes his popular technology blog, at
smist08.wordpress.com.
About the Technical Reviewer
Stewart Watkiss
is a keen maker who has created
numerous physical computing projects
using a variety of computers and
microcontrollers. He is author of the
Apress titles Learn Electronics with
Raspberry Pi and Beginning Game
Programming with Pygame Zero. He
studied at the University of Hull, where
he earned a master’s degree in
electronics engineering, and more
recently at Georgia Institute of
Technology, where he earned a master’s
degree in computer science.
Stewart also volunteers as a STEM ambassador, helping teach
programming and physical computing to schoolchildren and at
Raspberry Pi events. He has created numerous resources for those
wanting to learn more about electronics and computing which are
available on his website (www.penguintutor.com).
© The Author(s), under exclusive license to APress Media, LLC, part of Springer
Nature 2024
S. Smith, RISC-V Assembly Language Programming, Maker Innovations Series
https://doi.org/10.1007/979-8-8688-0137-2_1

1. Getting Started
Stephen Smith1
(1) Gibsons, BC, Canada

Most people are familiar with Intel or AMD microprocessors lying at the
heart of their desktop, laptop, or server, and, similarly, most cell phones
and tablets use ARM microprocessors. RISC-V is the new entry built
around open-source concepts. Before getting into the details of RISC-V,
let’s first look at the history and evolution of modern microprocessors.

History and Evolution of the RISC-V CPU


At the heart of every computer, there is at least one Central Processing
Unit (CPU) that executes the programs that you run. Most modern
computers have several CPUs, the main one to run the operating system
and user programs, then several helper CPUs to offload tasks like
network communications. Solid-state drives (SSDs) and hard drives
(HDDs) each contain a CPU to read and store the data. Nearly every
household appliance from microwaves to thermostats contains a CPU
that interprets button pushes and performs the appliance’s function. A
modern automobile typically contains 1000 to 3000 CPU chips to
control everything from the infotainment system to the power steering
to the braking systems. CPUs range in price from a few cents to
thousands of dollars, and each runs its own special machine code to
execute programs.
Early CPUs, such as the IBM 360 mainframe, were large,
complicated, and comprised of thousands of discrete components. In
1971, Intel debuted the Intel 4004, a single chip 4-bit CPU that allowed
the proliferation of handheld calculators. This led to more advanced
CPUs such as the MOS Technology 6502 which had the right
combination of being both affordable yet powerful enough to create
both the personal computer and video game industries with products
like the Apple II and Nintendo Entertainment System.
IBM entered the PC market in 1981 using the more complex Intel
8088 CPU. This CPU was powerful and flexible with 16-bit addressing
and variable length machine code instructions. This started a trend of
single-chip CPUs adding complexity with the goal of becoming
mainframes on the desktop. Intel quickly introduced new chips with
more and more advanced functionalities to empower 32-bit and then
64-bit processing, vector operations, memory protection, multi-tasking,
and more. This process added to the chip's complexity along with the
underlying instruction set.
Competitors saw this and thought they could compete with Intel’s
Complex Instruction Set Computers (CISC) by introducing simplified
Reduced Instruction Set Computers (RISC). These computers wouldn’t
have the baggage of maintaining compatibility with older chips, they
would start out at 32- or 64-bits. Their instructions would be a fixed
width and there would be fewer of them to allow faster instruction
decoding. Each instruction would run in 1 clock cycle. Early RISC
processors were typically used in high-end UNIX workstations, so
consequently they never achieved the shipment volume and economies
of scale to effectively compete with Intel.
In 1982, Acorn Computers, which produced the BBC
Microcomputer, was looking to upgrade their line of computers from
using the now aging 6502. The engineers at Acorn did not want to move
to the Intel architecture and become another PC clone. Instead, they
wanted the simplicity of the 6502, but modernized. They took the
daring step of designing their own CPU, called the ARM CPU based on
the RISC philosophy.
If the ARM was only used in Acorn Computers, it probably would
have died out. However, towards the end of the 1990s, Steve Jobs
decided to use the ARM processor in the Apple iPod. The reason being
that because of its simplified instruction set, an ARM processor didn’t
use much power, and this allowed longer battery life in a portable
device.
With the success of the iPod, ARM reached a reasonable production
volume for more research and development (R&D), then with the
introduction of the iPhone, ARM usage exploded as ARM processors are
used in nearly every phone and tablet in production. Intel finally had
competition from a RISC processor.
Today, most Intel processors implement a RISC core that executes
the Intel machine code using multiple RISC instructions. ARM has
become more complex as it supports both 32- and 64-bit instructions
using different formats. A major complaint against both is that to use
compatible machine code with either ARM or Intel processors requires
expensive licensing agreements with the parent companies.
Enter RISC-V, an open standards RISC-based machine, where anyone
can produce a compatible CPU without paying anyone licensing fees.
Creating a new CPU machine language is expensive as you need high-
level language compilers and operating support. If you create a CPU
that executes RISC-V instructions, then you can use the standard RISC-V
version of Linux and the standard GNU language toolchain for
compiling high-level languages. The RISC-V project started in 2010 at
the University of California, Berkeley, and RISC-V is the fifth version of
the architecture. It supports 32-, 64-, and 128-bit processors. It is
designed to run on everything from microcontrollers costing pennies to
superscalar supercomputers costing millions. We’ve reached a point
where many RISC-V CPUs and computers are appearing. This book will
explore the architecture and describe how to program these RISC-V
CPUs at the lowest machine code level.

What You Will Learn


You will learn Assembly Language programming for RISC-V CPUs
running in 32- or 64-bit mode. Everything you will learn is directly
applicable to all RISC-V devices from the smallest microcontrollers to
the largest superscalar supercomputers. Learning Assembly Language
for one processor gives you the tools to learn it for another processor,
such as ARM processors typically used in mobile devices.
In all devices, the RISC-V processor isn’t just a CPU, it’s a system on a
chip. This means that most of the computers are all on one chip. When a
company is designing a device, they can select various modular
components to include on their chip. Typically, this contains a RISC-V
processor with multiple cores, meaning that it can process instructions
for multiple programs running at once. It likely contains several co-
processors for things like floating-point calculations, a Graphics
Processing Unit (GPU), and various communications protocols.
The RISC-V instruction set is modular. Each RISC-V CPU will
implement a set of modules to provide the functionality its users
require. First there is a base module consisting of the basic integer
instructions. There are three common base instruction sets—one for
32-bit, one for 64-bit, and a slimmed down subset of the 32-bit one for
minimal embedded processors.
The base set provides sufficient functionality to perform integer
arithmetic, logic, comparisons, and branches. Then additional
instructions are added in optional modules, for instance, integer
multiplication and division are in the “M” module. Low-cost embedded
processors will only implement a few basic modules, whereas a more
powerful CPU intended to be used in a full Linux-based computer might
implement a dozen modules. Table 1-1 contains the three main base
versions of the instruction sets that are covered in this book.

Table 1-1 Base Instruction Sets

Name Description
RV32I Base Integer Instruction Set, 32-bit
RV32E Base Integer Instruction Set (embedded), 32-bit
RV64I Base Integer Instruction Set, 64-bit

Table 1-2 contains the main instruction set extensions. For a


complete list, consult the specifications posted at riscv.org.

Table 1-2 Instruction Set Extensions

Name Description
M Standard Extension for Integer Multiplication and Division
A Standard Extension for Atomic Instructions
F Standard Extension for Single-Precision Floating-Point
Name Description
D Standard Extension for Double-Precision Floating-Point
Zicsr Control and Status Register (CSR) Instructions
Zifencei Instruction-Fetch Fence
G Shorthand for the IMAFDZicsr_Zifencei base and extensions
C Standard Extension for Compressed Instructions
Working at this low level is technical and time-consuming, so why
would a programmer want to write Assembly Language code?

Ten Reasons to Learn Assembly Language


Programmierung
Most programmers write in a high-level programming language like
Python, C#, Java, JavaScript, Go, Julia, Scratch, Ruby, Swift, or C. These
highly productive languages are used to write major programs from the
Linux operating system to websites like Facebook, to productivity
software like LibreOffice. If you learn to be a good programmer in a
couple of these, you can potentially find a well-paying interesting job
and write some great programs. If you create a program in one of these
languages, you can easily get it working on numerous operating
systems on multiple hardware architectures. You never have to learn
the details of all the bits and bytes, and these can remain safely under
the covers.
When you program in Assembly Language, you are tightly coupled
to a given CPU and moving your program to another requires a
complete rewrite of your program. Each Assembly Language
instruction does only a fraction of the amount of work, so to do
anything takes a lot of Assembly statements. Therefore, to do the same
work as, say, a Python program takes an order of magnitude larger
amount of effort, for the programmer. Writing in Assembly Language is
harder, as you must solve problems with memory addressing and CPU
registers that are all handled transparently by high-level languages. So
why would you want to learn Assembly Language programming?
Here are 10 reasons to learn and use Assembly Language:
1. To write more efficient code: Even if you don’t write Assembly
Language code, knowing how the computer works internally
allows you to write more streamlined code. You can make your
data structures easier to access and write code in a style that
allows the compiler to generate more effective code. You can make
better use of computer resources, like co-processors, and use the
given computer to its fullest potential.

2. To write your own operating system: The core of the operating


system that initializes the CPU handles hardware security and
multi-threading/multi-tasking requires Assembly code.

3. To create a new programming language: If it is a compiled


language, then you need to generate the Assembly code to execute.
The quality and speed of your language is largely dependent on
the quality and speed of the Assembly Language code it generates.

4. To make computers run faster: The best way to make Linux


faster is to improve the GNU C Compiler. If you improve the RISC-V
Assembly Language code produced by GNU C, then every program
compiled by GCC benefits.

5. To interface a computer to a hardware device: When


interfacing a computer through USB or GPIO ports, the speed of
data transfer is highly sensitive as to how fast a program can
process the data. Perhaps, there are a lot of bit-level
manipulations that are easier to program in Assembly Language.

6. To do faster machine learning or 3D graphics programming:


Both applications rely on fast matrix mathematics. If you can make
this faster with Assembly and/or using the co-processors, then
you can make AI-based robots or video games that much better.

7. To boost performance: Most large programs have components


written in different languages. If a program is 99% C++, the other
1% could be Assembly, perhaps giving a program a performance
boost or some other competitive advantage.
8. To create a new single-board computer: New boards have some
Assembly Language code to manage peripherals included with the
board. This code is usually called a BIOS (basic input/output
system).

9. To look for security vulnerabilities in a program or piece of


hardware: Look at the Assembly code to do this, otherwise you
may not know what is really going on, and hence where holes
might exist.

10. To look for Easter eggs in programs: These are hidden


messages, images, or inside jokes that programmers hide in their
programs. They are usually triggered by finding a secret keyboard
combination to pop them up. Finding them requires reverse
engineering the program and reading Assembly Language.

Now that we have some background on Assembly Language, we’ll


look at some choices for running RISC-V Assembly Language code.

Running Programs on RISC-V Systems


Due to the modular nature of RISC-V, there are a lot of possibilities for
running programs. This book will provide details on the following three
specific systems:
1. RISC-V-based Linux computer such as the Starfive Visionfive 2:
This is the easiest way to play with RISC-V Assembly Language,
since everything is done on the same computer. The CPU on the
Visionfive 2 board supports the RV64GC set of RISC-V extensions.

2. RISC-V simulator running on an Intel/AMD-based Windows or


Linux computer: Not everyone has a RISC-V computer yet, but
don’t let that stop you. You can simulate RISC-V running full Linux.

3. RISC-V microcontroller: There are many of these such as the


Espressif ESP32-C3 DevKit. First of all, write a program, then
compile it on another computer, such as a Linux laptop, and finally
download the compiled program to the microcontroller to run. This
is an important usage of RISC-V Assembly Language, but you will be
limited to a few basic instruction modules, namely, RV32IMC.
There are many other possibilities that also work, but you will need
to adapt the instructions for the supported systems. Next, we look at
how to set up each of these to assemble and run a simple Assembly
Language program to print out “Hello RISC-V World!”

Coding a Simple “Hello World” Program


Computers operate on binary data consisting of zeros and ones;
however, humans do not think this way. As a result, humans develop
tools to assist us in interacting with computers. One such tool is the
GNU Assembler which takes a human readable version of an Assembly
Language program and converts it to the zeroes and ones that the RISC-
V processor understands. In this section, we will present a simple
program without going into detail. The details will be filled in over the
following chapters. In this chapter, we’ll take the program and look at
several ways of Assembling and running it. First, we’ll look at running it
on the Starfive Visionfive 2 SBC under Linux.

Hello World on the Starfive Visionfive 2


The state of Linux on RISC-V computers is evolving quickly. At the time
of writing this book, the Debian Linux install image for the Starfive
Visionfive 2 computer is quite minimal and does not even include a web
browser. Please follow the instructions in its Quick Start Guide for the
most up-to-date information. These instructions will also give an idea
of what is required for other RISC-V-based Linux SBCs.
At the time of the writing of this book, these are the instructions to
set up the Visionfive 2. The steps are given in more detail in the
Visionfive’s Quick Start Guide. The Visionfive can run Linux from a
microSD card, an M.2 SSD drive, or from its internal firmware.
Before you start, you will need the following:
The Starfive Visionfive 2 board, USB keyboard, USB mouse, and HDMI
capable monitor
An microSD (Secure Digital) card
A burner program, like Balena Etcher
Secure Shell (SSH) program
Quick Start Guide
Internet connection
First, configure two dip switches on the motherboard to boot from
the preferred device. These instructions follow what is needed to boot
from a microSD card, but as long as the correct instructions are
followed, you can run Linux from any supported configuration.
1. Configure the two dip switches to eMMC.

2. Download the Debian Linux image for an SD card from Starfive’s


website: https://debian.starfivetech.com/. Next, burn it
onto an SD card using a program like Balena Etcher.

3. Place the SD card in the Visionfive 2 and turn the Visionfive on.

4. If you are using a hardwired Internet connection, you can skip this
step. When it boots to Linux, login, the password is “starfive.” Run
the Setup program and select your Wifi and enter the password.

5. Since the base image doesn’t contain a web browser, it is easiest to


perform the following steps using SSH from a host computer on the
same Wifi network. This way you can copy/paste commands from
the Quick Start Guide into the SSH program. Use “starfive.local” as
the host name.

ssh [email protected]

6. Next, the file system needs to be resized. If you don’t do this, you
can’t install any programs, since the base image has little free space.
This is a technical step and you should follow the instructions from
the Quick Start Guide carefully as you are deleting and recreating
disk partitions.

7. Now we perform the long step of installing the extra software that
includes web browsers and the development tools required for this
book. Use the scp command to copy the
“install_package_and_dependencies.sh” script to the computer and
run it. Enter the scp command from the host computer:

scp install_package_and_dependencies.sh
[email protected]:/home/user

8. Then the following commands from the SSH remote session.

chmod +x install_package_and_dependencies.sh
./install_package_and_dependencies.sh

Running this takes several hours, so it's a good time to go for


lunch. After this script completes, reboot the Visionfive 2.

9. Part of the previous shell script installs the GNU development tools.
If using a different Linux distribution of SBC, this may need to be
done manually using the command:

sudo apt install build-essential

10. After the computer reboots, login normally. There are now web
browsers, office tools, and software development tools.

11. Install a simple GUI text editor to use for programming. Use a
terminal-based text editor like vi if you wish. GEdit is a good
simple choice that can be installed with the following command:

sudo apt install gedit

With the computer setup, we are ready to write, assemble, and run a
simple “Hello World” program. In this chapter, we won’t worry about
the details of how this program works, rather we are ensuring we can
assemble, link, and run programs. We will examine how everything
works in detail in the following chapters.
Either download the source code from the Apress Github site or
type in the program in Listing 1-1 and save it as HelloWorld.S, where
capitalization is important.
#
# Risc-V Assembler program to print "Hello RISC-V
World!"
# to stdout.
#
# a0-a2 - parameters to linux function services
# a7 - linux function number
#

.global _start # Provide program starting


address to linker

# Setup the parameters to print hello world


# and then call Linux to do it.

_start: addi a0, x0, 1 # 1 = StdOut


la a1, helloworld # load address of
helloworld
addi a2, x0, 20 # length of our
string
addi a7, x0, 64 # linux write system
call
ecall # Call linux to
output the string

# Setup the parameters to exit the program


# and then call Linux to do it.

addi a0, x0, 0 # Use 0 return code


addi a7, x0, 93 # Service command code
93 terminates
ecall # Call linux to
terminate the program

.data
helloworld: .ascii "Hello RISC-V World!\n"
Listing 1-1 The Linux version of the Hello World program
Anything after a hash sign (#) is a comment. The code lines consist
of an optional label, followed by an opcode, possibly followed by several
parameters. To compile and run this program, create a file called build
that contains the contents of Listing 1-2:

as -o HelloWorld.o HelloWorld.S
ld -o HelloWorld HelloWorld.o
Listing 1-2 Build file for Hello World

After saving the build file, convert it to an executable file with the
following command:

chmod +x build

Now compile the program by running the build file and then the
resulting executable program with following commands:

./build
./HelloWorld

Figure 1-1 shows the result of running this. bash -x is used to show
the commands being executed.

Figure 1-1 Compiling and running the Hello World program

We’ve now written and executed our first Assembly Language


program. Next, let’s look at running Hello World on a RISC-V emulator.
Programming Hello World in the QEMU Emulator
Even without owning a genuine RISC-V processor, you can still emulate
a RISC-V-based computer using the QEMU emulator. QEMU is similar to
virtualization software like VMWare, except that the computer being
virtualized isn’t required to have the same CPU as the host system.
In this case, we’ll give instructions on how to install and run the
QEMU emulator on a Windows computer and emulate/virtualize a
RISC-V-based Linux system. Next, we will run exactly the same
programs that we run on the genuine RISC-V-based Starfive Visionfive
2.

Install QEMU on Windows


Here are the instructions to install QEMU on Windows and get a RISC-V
version of Linux up to the first login prompt. Before you start, you will
need the following:
QEMU software.
7-Zip or any uncompression program that understands xz format.
fw_jump.elf and uboot.elf. These are easy to install on Linux,
but a bit hard to find for Windows, so they are placed on the Apress
Github site under Chapter 1.
The QEMU documentation is extensive, but overwhelming. The
following are the steps required for this book:
1. Install QEMU. Download the Windows install image. Run the
downloaded program saying Yes to the Windows security prompts.

2. Add c:\Program Files\Qemu to the system PATH, assuming the


default installation folder.

3. Download the Ubuntu Server preinstalled image from


https://ubuntu.com/download/risc-v.

4. Use 7-Zip or any uncompression program that understands xz


format to extract the .img file from what you downloaded.
5. Rename the .img file as ubunturv.img, or change the name in the
commands that follow.

6. Add free space to the image with

qemu-img resize ubunturv.img +10G

This gives room to install programs once you start Linux.


7. To run the image, use fw_jump.elf and uboot.elf. These then
act as the emulated board’s BIOS.

8. Now we are ready to run QEMU with the rather long command:

qemu-system-riscv64 ^
-machine virt ^
-cpu rv64 ^
-m 2G ^
-device virtio-blk-device,drive=hd ^
-drive file=ubunturv.img,if=none,id=hd ^
-device virtio-net-device,netdev=net ^
-netdev
user,id=net,hostfwd=tcp::2222-:22 ^
-bios fw_jump.elf ^
-kernel uboot.elf ^
-append “root=LABEL=rootfs
console=ttyS0” ^
-nographic

In a Windows cmd prompt, at the time of this writing, not all


the cursor and other special characters translate properly. Rather
than logining in at the Linux prompt directly, use a ssh command to
login with

ssh -p 2222 ubuntu@localhost


Then in the ssh window, the cursor keys and other special
characters work properly.

Install QEMU on Linux


Now let’s do the same thing for Linux.
1. Install QEMU with

sudo apt install qemu-system-riscv64


sudo apt install u-boot-qemu opensbi

2. Download the Ubuntu Server preinstalled image from


https://ubuntu.com/download/risc-v.

3. From the downloaded Ubuntu image, extract the img file from the
xz file with

unxz < downloaded_file_name.img.xz > ubunturv.img

4. Expand the image, so there is some disk space to play around with

sudo qemu-img resize ubunturv.img +10G

5. Now we are ready to run with the rather long qemu command:

qemu-system-riscv64 \
-machine virt \
-cpu rv64 \
-m 2G \
-device virtio-blk-device,drive=hd \
-drive file=ubunturv.img,if=none,id=hd \
-device virtio-net-device,netdev=net \
-netdev
user,id=net,hostfwd=tcp::2222-:22 \
-bios /usr/lib/riscv64-linux-
gnu/opensbi/generic/fw_jump.elf \
-kernel /usr/lib/u-boot/qemu-
riscv64_smode/uboot.elf \
-object rng-
random,filename=/dev/urandom,id=rng \
-device virtio-rng-device,rng=rng \
-append “root=LABEL=rootfs
console=ttyS0” \
-nographic

Compiling in Emulated Linux


Whether using Windows or Linux to host QEMU, booting Linux under
the emulator will eventually lead you to a login prompt. The initial user
id/password is ubuntu/ubuntu. During the first time logging in, Linux
will force to change the password. The computer name is also ubuntu
which can be changed if needed. Once logged in, we can add the GNU
Compiler Collection with

sudo apt update


sudo apt install build-essential

This will also install GDB and a few other GCC-related tools.
Next, either type the HelloWorld.S program from the previous
section into vi to save it to the new image or copy the program to this
image using scp:

scp -P 2222 HelloWorld.S


ubuntu@localhost:/home/ubuntu

Then compile and run the program:

as -o HelloWorld.o HelloWorld.S
ld -o HelloWorld HelloWorld.o
./HelloWorld

Figure 1-2 shows the output of this process.


Figure 1-2 Compiling and running Hello World in the QEMU emulator
Now, let’s look at running Hello World on a Espressif ESP32-C3
Devkit microcontroller.

About Hello World on the ESP32-C3


Microcontroller
The Espressif ESP32-C3 Devkit is a RISC-V-based microcontroller
similar to a Raspberry Pi Pico. There are many RISC-V microcontrollers
on the market, but this one has an extensive SDK allowing
programming in MicroPython, C/C++, or Assembly Language. The
documentation is extensive and Espressif has a lot of experience in the
microcontroller world.
When developing for a microcontroller, you need a host computer
where you write the code and compile your program. You then
download the resulting program to run, usually through a USB cable.
The host computer can be a Windows, MacOS, or Linux-based
computer. The online Espressif Getting Started Guide is recommended
to install the Espressif SDK on your computer. The examples in this
book will be developed on a Windows-based computer, but this doesn’t
really matter. To install the Espressif SDK on Windows is quite simple,
just requiring that a standard Windows installation program be run.
Projects in the Espressif SDK use the CMake system for building and
are more complex than what we have seen so far. The easiest way to get
a project running quickly is to take one of the SDK’s example projects,
then transform it into what is required. The Espressif SDK contains a
Hello World program written in C. Let’s convert it to a Hello World
program written entirely in Assembly Language. Take the example
program located at the following link: C:\Espressif\frameworks\esp-
idf-v5.0.2\examples\get-started\hello_world, to create our hello_world
project:
1. Copy the SDK example hello_world project to a new folder, say
hello_world_asm.

2. Change main\CMakeLists.txt to replace the source file


hello_world_main.c with hello_world_main.S.

3. Delete main\hello_world_main.c and create


main\hello_world_main.S from Listing 1-2.

The “Hello World” program is a little different than the Linux


version and contained in Listing 1-3:

#
# Risc-V Assembler program to print "Hello RISC-V
World!"
# to the Espressif SDK monitor program through the
microUSB.
#
# a0 - address of helloworld string
#

.global app_main # Provide program starting


address to linker

# Setup the parameter to print hello world


# and then call SDK to do it.

app_main:
la a0, helloworld # load address of
helloworld
call puts # Call sdk to output
the string
j app_main # loop forever

.data
helloworld: .asciz "Hello RISC-V World!"
Listing 1-3 Espressif version of the Hello World program
We build the program with:

idf.py build

Note Remember to use the special version of the Command (CMD)


prompt on your desktop that the Espressif SDK install added. This
CMD contains all the correct environment variables required for a
successful build.

The first time CMD runs, it takes a long time since it needs to build the
entire SDK as part of the process. On subsequent builds, it is much
quicker as it only needs to build the files that have changed. Figure 1-3
shows the output of the build process on one of these following builds.
Figure 1-3 Building the Espressif version of the Hello World program
And then run it with the following:

idf.py -p com4 flash monitor

Figure 1-4 shows the end of the download process, followed by the
start of the program.
Figure 1-4 Running Hello World on the Espressif RISC-V microcontroller

Note The required com port might not be com4, to check the
correct port, run the Windows Device Manager, open the “Ports
(COM & LPT)” section, and note which COM port is associated with
the “Silicon Labs CP210x USB to UART Bridge.”

In the Linux version of the program, the program terminated after


printing the “Hello RISC-V World!” string once. Microcontrollers don’t
have an operating system to exit to, so they are usually implemented as
an infinite loop that runs forever, as was done in this simple example.
To exit the monitor, use Control-].

Summary
In this chapter, we introduced the RISC-V processor and Assembly
Language programming along with why Assembly Language is used. We
covered how to set up three possible development environments for
Assembly Language programming using RISC-V.
In Chapter 2, “Loading and Adding,” we will start to understand the
details of the programs presented, including the basics of Assembly
Language instructions and CPU registers. We’ll learn how numbers are
represented in a computer and how basic integer addition and
subtraction work.

Exercises
1. Setup your RISC-V development environment. Whether it is on a
Linux Single Board Computer (SBC) such as the Starfive Visionfive
2, running in the QEMU emulator or using a microcontroller like the
Espressif ESP32-C3.

2. Modify the “Hello RISC-V World!” string to a different string. For the
Linux versions, remember to modify the string length as well.
© The Author(s), under exclusive license to APress Media, LLC, part of Springer
Nature 2024
S. Smith, RISC-V Assembly Language Programming, Maker Innovations Series
https://doi.org/10.1007/979-8-8688-0137-2_2

2. Loading and Adding


Stephen Smith1
(1) Gibsons, BC, Canada

The goal of this chapter is to load various integer values into the CPU
and perform basic addition and subtraction operations on these values.
This sounds simple, but at the low level of Assembly Language, this can
get complicated. In this chapter, we will go step-by-step through the
various forms of the add, sub, and Shift instructions, to lay the
groundwork on how all instructions work, especially in the way they
handle parameters. This is so that in subsequent chapters, we can
proceed at a faster pace as we encounter the rest of the RISC-V
instruction set.
Before getting into the various Assembly Language instructions, we
will discuss how the RISC-V CPU represents positive and negative
numbers.

Computers and Numbers


We typically represent numbers using base ten. The common theory is
we do this because we have ten fingers to count with. This means a
number like 387 is really a representation for

387 = 3 ∗ 102 + 8 ∗ 101 + 7 ∗ 100


= 3 ∗ 100 + 8 ∗ 10 + 7
= 300 + 80 + 7
There is nothing special about using ten as our base, and a fun
exercise in math class is to do arithmetic using other bases. In fact, the
Mayan culture used base 20, perhaps because we have 20 digits: ten
fingers and ten toes.
Computers don’t have fingers and toes, just switches that are either
on or off. As a result, it is natural for computers to use base two
arithmetic. Thus, to a computer, a number like 1011 is represented by
the following:

1011 = 1 ∗ 23 + 0 ∗ 22 + 1 ∗ 21 + 1 ∗ 20
= 1 ∗ 8 + 0 ∗ 4 + 1 ∗ 2 + 1
= 8 + 0 + 2 + 1
= 11 (decimal)

This is great for computers, but we use four digits for the decimal
number 11 rather than two digits. The big disadvantage for humans is
that writing out binary numbers is tiring, because they take up so many
digits.
Computers are incredibly structured, so all their numbers are the
same size. When designing computers, it doesn’t make sense to have a
variety of differently sized numbers, so a few common sizes have
become standard as described in the following paragraph.
A byte is eight binary bits or digits. In our preceding example with
four bits, there are 16 possible combinations of 0s and 1s. This means
four bits can represent the numbers 0 to 15. This means it can be
represented by one base 16 digit. Base 16 digits are represented by the
numbers 0 to 9 and then the letters A–F for 10–15. We can then
represent a byte (eight bits) as two base 16 digits. We refer to base 16
numbers as hexadecimal (Figure 2-1).

Figure 2-1 Representing hexadecimal digits

Since a byte holds eight bits, it can represent 28 (256) numbers.


Thus, the byte E6 represents

E6 = e ∗ 161 + 6 ∗ 160
= 14 ∗ 16 + 6
= 230 (decimal)
= 1110 0110 (binary).
We call a 32-bit quantity a word, and it is represented by four bytes.
You might see a string like B6 A4 44 04 as a representation of 32 bits of
memory, or one word of memory, or perhaps the contents of one
register. If we use a 64-bit RISC-V processor, then a word is still 32-bits,
and 64-bit quantities are referred to as doublewords, and we would see
a string of eight bytes to represent one doubleword of data.
If this is confusing or scary, do not worry. The tools will do all the
conversions for you. It’s just a matter of understanding what is
presented to you on the screen. Also, if an exact binary number needs to
be specified, that is usually done in hexadecimal, although all the tools
accept all the formats.
A handy tool is the Linux Gnome Calculator (Figure 2-2). The Gnome
Calculator has a Programming Mode which shows a numbers
representation in multiple bases at once. This calculator is included
with Ubuntu Linux with the Gnome desktop. To install it on the
Visionfive 2, enter the following command line:

sudo apt-get install gnome-calculator

In “Programmer Mode,” conversions can be done with numbers


shown in several formats at once.
This is how data is represented on a computer. There is more
complexity in how signed integers are represented and how arithmetic
works.
Another random document with
no related content on Scribd:
Fig. 3.

Fig. 3. represents:—the proventricular sac thrust forward, f, g, h, the


gizzard, h; the duodenum, i, j, k, pulled to the right side; the
convolutions of the intestine, l, m, under the kidneys, the cœca, n;
the rectum, o, and the cloaca, p.
The proventricular glands are very numerous, but not so closely
placed as is usual, although scattered over a much larger extent,
from e to g in Fig. 2. Between the termination of the glands and the
stomach there is a portion destitute of glandules. The stomach or
gizzard has its muscular coat thick, its tendons moderate, its inner
surface covered with a rather thick but not very hard epithelium,
which is more prolonged on two opposite sides, although in the
fundus it is complete.
This curious digestive apparatus agrees very nearly with that
described and figured by Sir Everard Home as that of Alca Alle.
The stomach, it is seen, is excessively large in proportion to the size
of the bird; but why it should be so, and moreover be curved in this
manner, is not very obvious. Conjectures are easily made, and might
run in this form. This little bird, which wanders over the face of the
ocean, subsisting upon garbage, oily and fatty substances, small
fishes, and even sea-weeds, requires a large stomach for the
reception of its heterogeneous fare, which not being always very
nutritious or easily digestible, must be very plentifully intermixed with
the gastric juices, and detained a considerable time; which
conditions are accordingly provided for by the very great number and
extensive dispersion of the proventricular glandules, and the curve of
the organ. Should any hard substances, as crustacea, be introduced,
they are pounded by the gizzard; but as the bird is little addicted to
feeding on such substances, that organ is reduced to a very small
size.
The aperture of the glottis is 1 1/2 twelfth long. The trachea is 1 inch
7 twelfths in length, wide, flattened, its diameter from 2 twelfths to
1 1/2 twelfth; its rings unossified, 82 in number. The bronchi are
short, wide, of about 12 half rings.
GREAT AUK.

Alca impennis, Linn.


PLATE CCCXLI. Adult.

The only authentic account of the occurrence of this bird on our


coast that I possess, was obtained from Mr Henry Havell, brother
of my Engraver, who, when on his passage from New York to
England, hooked a Great Auk on the banks of Newfoundland, in
extremely boisterous weather. On being hauled on board, it was left
at liberty on the deck. It walked very awkwardly, often tumbling over,
bit every one within reach of its powerful bill, and refused food of all
kinds. After continuing several days on board, it was restored to its
proper element.
When I was in Labrador, many of the fishermen assured me that the
“Penguin,” as they name this bird, breeds on a low rocky island to
the south-east of Newfoundland, where they destroy great numbers
of the young for bait; but as this intelligence came to me when the
season was too far advanced, I had no opportunity of ascertaining its
accuracy. In Newfoundland, however, I received similar information
from several individuals. An old gunner residing on Chelsea Beach,
near Boston, told me that he well remembered the time when the
Penguins were plentiful about Nahant and some other islands in the
Bay.
The egg is very large, measuring five inches in length, and three in
its greatest breadth. In form it resembles that of the Common
Guillemot; the shell is thick and rather rough to the touch; its colour
yellowish-white, with long irregular lines and blotches of brownish-
black, more numerous at the larger end.

Alca impennis, Linn. Syst. Nat. vol. i. p. 201.—Lath. Ind. Ornith. vol. ii. p. 791.
Great Auk, Nuttall, Manual, vol. ii. p. 553.

Adult in Summer. Plate CCCXLI. Figs. 1, 2.


Bill as long as the head, feathered as far as the nostrils, beyond
which it is very high, exceedingly compressed, tapering, and slightly
declinate. Upper mandible with the dorsal line straight for an inch
and a quarter, then declinate and decurvate to the end, the ridge
very narrow, broader at the base; the sides nearly flat, with a basal
ridge succeeded by a deep groove, then a large flat space,
succeeded by eight oblique curved ridges, the edges sharp toward
the end, the tip decurved and obtuse. Nostrils marginal, linear, short,
pervious, but concealed by the feathers. Lower mandible with the
angle long, the sides extremely narrow and linear for half their
length, the horny part not being extended over the bone, which is
covered with feathers, afterwards deep and compressed, with the
dorsal line at first convex, then ascending and concave to the end,
the sides flat, with about ten transverse ridges, the edges sharp, the
tip deflected.
Head large, oblong, anteriorly narrowed. Eyes rather small. Neck
short and thick. Body compact and full. Wings extremely small, but
perfectly formed. Feet placed far behind, short, very strong; tarsus
short, compressed, anteriorly scutellate, laterally covered with
angular scales, those on the hind part very small. Hind toe wanting;
third toe longest, outer nearly as long, inner much shorter, lateral
toes marginate, all with numerous scutella and several rows of
angular scales above, and connected by reticulated webs. Claws
rather small, narrow, arched, convex above, and obtuse.
Plumage close, blended, very soft, on the head and neck short and
velvety. Wings diminutive, much pointed; the primaries tapering to an
acute point, the first longest, the rest rapidly graduated, their coverts
long; secondaries short and broad, scarcely longer than their
coverts. Tail short, pointed, of fourteen feathers.
Bill black, with the grooves between the transverse ridges white. Iris
hazel. Feet and claws black. Fore part of the neck below, and all the
lower parts white, of which colour also is a large oblong patch before
each eye, and the tips of the secondary quills; the rest black, the
throat and sides of the neck tinged with chocolate-brown, the wings
with greyish-brown, the head, hind neck, and back glossed with
olive-green.
Length to end of tail 29 inches, to end of wings 23 3/4, to end of
claws 31 1/2, to carpal joint 18 1/2; extent of wings 27 1/4; wing from
flexure 7 1/8; tail 2 7/8, bill along the ridge 3 5/8, along the edge of
lower mandible 4 1/2, greatest depth of upper mandible 1, depth of
lower 5/8; width of gape 1 7/8; tarsus 2; middle toe 2 5/8, its claw 5/8;
1/2 1/2 1/2
outer toe 2 5/8; its claw 3 /8; inner toe 2 /8, its claw 4 /8.
GOLDEN-EYE DUCK.

Fuligula clangula, Bonap.


PLATE CCCXLII. Male and Female.

You have now before you another of our Ducks, which at least
equals any of the rest in the extent of its migrations. Braving the
blasts of the north, it visits the highest latitudes in spring, and returns
at the approach of winter, spreading over the whole country, as if it
seemed not to care in what region it spends its time, provided it find
abundance of water. Now propelling itself gaily, it may be seen
searching the pebbly or rocky bottom of the Ohio, or diving deep in
the broad bays of Massachusetts or the Chesapeake. Presently it
emerges with a cray-fish or a mussel held firmly in its bill. It shakes
its head, and over its flattened back roll the large pearly drops of
water, unable to penetrate the surface of its compact and oily
plumage. The food is swallowed, and the bird, having already
glanced around, suddenly plunges headlong. Happy being! Equally
fitted for travelling through the air and the water, and not altogether
denied the pleasure of walking on the shore; endowed with a
cunning, too, which preserves you from many at least of the attempts
of man to destroy you; and instinctively sagacious enough to place
your eggs deep in the hollow of a tree, where they are secure from
the nocturnal prowler, and, amid the down of your snowy breast, are
fostered until the expected young come forth. Then with your own bill
you carry your brood to the lake, where under your tender care they
grow apace. The winged marauders, rapid as their flight may be,
cannot injure you there; for while your young ones sink into the deep
waters, you arise on whistling wings, and, swifter than Jer Falcon,
speed away.
In South Carolina the Golden-eye is abundant during winter, when it
at times frequents the reserves of the rice-planters. I have also met
with it on the water-courses of the Floridas at that season. From
these countries westward and northward, it may be found in all parts
of the Union where the waters are not frozen. It is seldom seen on
small ponds entirely surrounded by trees, but prefers open places,
and on the Ohio is generally found in the more rapid parts, on the
eddies of which it dives for food.
This species exhibits a degree of cunning which surpasses that of
many other Ducks, and yet at times it appears quite careless. When I
have been walking, without any object in view, along the banks of the
Ohio, between Shippingport and Louisville, I have often seen the
Golden-eyes, fishing almost beneath me, when, although I had a
gun, they would suffer me to approach within an hundred paces. But
at other times, if I crawled or hid myself in any way while advancing
towards them, with a wish to fire at them, they would, as if perfectly
aware of my intentions, keep at a distance of fully two hundred
yards. On the former occasion they would follow their avocations
quite unconcernedly: while on the latter, one of the flock would
remain above as if to give intimation of the least appearance of
danger. If, in the first instance, I fired my gun at them, they would all
dive with the celerity of lightning, but on emerging, would shake their
wings as if in defiance. But if far away on the stream, when I fired at
them, instead of diving, they would all at once stretch their necks,
bend their bodies over the water, and paddle off with their broad
webbed feet, until the air would resound with the smart whistling of
their wings, and away they would speed, quite out of sight, up the
river. In this part of the country, they are generally known by the
name of “Whistlers.”
I have observed that birds of this species rarely go to the shores to
rest until late in the evening, and even then they retire to secluded
rocks, slightly elevated above the surface, or to the margins of sand-
bars, well protected by surrounding waters. In either case, it is
extremely difficult for a man to get near them; but it is different with
the sly Racoon, which I have on several occasions surprised in the
dawn, feeding on one which it had caught under night. Yet, on some
of the bays of our sea-coasts, the Whistlers are easily enticed to
alight by the coarsest representations of their figures in wooden
floats, and are shot while they pass and repass over the place to
assure themselves that what they see is actually a bird of their own
kind. This mode is successfully followed in the Bay and Harbour of
Boston in Massachusetts, as well as farther to the eastward.
The Golden-eye is rarely if ever seen in the company of any other
species than those which are, like itself, expert divers; such, for
example, as the Mergansers, or the Buffel-headed Duck: and it is
very rare to see all the individuals of a flock immersed at once.
Sometimes, when suddenly surprised, they immediately dive, and do
not rise again until quite out of gun-shot. When wounded, it is next to
impossible to catch them; for their power of remaining under water is
most surprising, and the sooner one gives up the chase the better.
The Golden-eye Ducks manifest a propensity to adhere to a place
which they find productive, and that to a most extraordinary degree.
One day, while approaching the shallow fording-place of Canoe
Creek, near Henderson, in Kentucky, I observed five Whistlers
fishing and swimming about. They allowed me to advance to within a
few yards of the shore, when, swimming close together, and shaking
their necks, they emitted their rough croaking notes. Not being
desirous of shooting them, I slapped my hands smartly together,
when in an instant they all went down, but suddenly rose again, and
running as it were over the water for about ten yards, took flight,
passed and repassed several times over the ford, and alighted on
the large branches of a sycamore that hung over the creek, at no
greater distance from where I stood than about twenty yards. This
was the first time in my life that I had seen Golden-eyes alight on a
tree. I waded to the opposite side, and gazed upon them with
amazement for several minutes. When on the eve of pursuing my
course, one of them, gliding downwards with nearly closed wings,
launched upon the water, and at once dived. The other four followed
one after another, somewhat in the manner of Pigeons or Starlings,
as if to ascertain whether some danger might not still exist. I left
them at their avocations, and soon after met a family of country
people going to Henderson, one of whom asked me respecting the
depth of the ford, to which I replied that the water was low, and
added that they should be careful lest some ducks that I had left
there might frighten the horses on which the women were. The good
folks, with whom I was acquainted, laughed, and we parted.
About four o’clock, as I was returning, with a fine Turkey-cock slung
to my back, I met the same party, who told me that, “sure enough,”
the ducks were at the ford, and I was likely to have “a good crack at
them.” There they were when I went up, and I forced them to fly off;
but as I was proceeding, and not more than fifty yards beyond the
creek, I heard their splashings as they again alighted. In the course
of a fortnight I visited the place several times, but never missed
finding these five ducks there. This led me to inquire as to the cause,
and, having undressed, I waded out barefooted, and examined the
bottom, which I found to be composed of rather hard blue clay, full of
holes bored by cray-fish. But to make myself quite sure that these
creatures formed the attraction to the Ducks, I watched an
opportunity, and shot two of the latter, the examination of which
satisfied me on the subject.
I had long before this been convinced, that an abundant supply of
food afforded a powerful attraction to migrating birds, and on this
subject you may remember my remarks in the articles of the Wild
Turkey and Passenger Pigeon, in the first volume of this work; but I
had not then, nor have I since, seen so strong an instance of
pertinacity in attachment to a particular spot.
The flight of this species is powerful, extremely rapid, and
wonderfully protracted. It passes along with a speed equal to that of
any of the Duck tribe, and I believe can easily traverse the space of
ninety miles in an hour. The whistling of its wings may be distinctly
heard when it is more than half a mile distant. This statement may be
found to be in contradiction to those of probably every previous
writer, for it has been a general opinion, that the greater the extent of
wing the more rapid is the flight, which is anything but correct. On
flying from the water, they proceed for a considerable distance very
low, not rising to any height until they have advanced several
hundred yards.
The only nest of the Golden-eye which I have examined, I
discovered, on the 15th of June, on the margin of a small creek
about eight miles from Green Bay. The female left it, probably to go
in search of food, whilst I was sitting under the tree in which it was,
thinking more of my peculiar situation than of birds of any kind, for I
was almost destitute of ammunition, and bent on returning to my
family, then in Louisiana. How exciting are such moments to the
ardent observer of Nature! In an instant, hunger, fatigue, even the
thoughts of my beloved wife and children, vanished; and in a few
minutes I was safely lodged on the tree, and thrusting my arm into
the cavity of a large broken branch. Nine beautiful, greenish, smooth
eggs, almost equally rounded at both ends, were at my disposal.
They were laid on some dry grass of the kind that grew on the edges
of the creek, and were deeply imbedded in the down of the bird. Not
being then aware of the necessity of measuring or keeping eggs, I
roasted them on some embers, and finding them truly delicious,
soon satisfied my hunger. While I was eating them, the bird returned,
but no male was to be seen. Whether many of these birds breed
within the limits of the Union I cannot tell. Dr Richardson says they
are abundant in the Fur Countries, and Dr Townsend states, that
they are plentiful on the Rocky Mountains and along the north-west
coast of America.
Of the changes which the young males undergo, nothing is known
beyond the fact, that the young of both sexes resemble the adult
female, until the approach of the first spring, when their general
migration northward removes them from our observation.
At the approach of spring, I have observed this species swell the
throat and the feathers of the head, and emit their rough croaking
notes very frequently. The males at this period become very
pugnacious, though, after all, they remove northward together,
preceding the females for at least a fortnight. They usually spend the
autumn and the earlier parts of winter separate from the females.
These birds have, like the Goosanders, a habit of shaking their
heads violently on emerging from the water Their flesh is fishy, and
in my opinion unfit for being eaten, unless in cases of excessive
hunger. The food of this species, while on fresh water, consists of
fish of various kinds, mollusca, young frogs, tadpoles, crayfish, and, I
believe, some kinds of grass. When on salt water, they feed
principally on bivalves and fishes of different species.

Anas Clangula, Linn. Syst. Nat. vol. i. p. 201.—Lath. Ind. Ornith. vol. ii. p.
867. Male.
Anas Glaucion, Linn. Syst. Nat. vol. i. p. 201.—Lath. Ind. Ornith. vol. ii. p.
867. Female and Young.
Golden-eye, Anas Clangula, Wils. Amer. Ornith. vol. viii. p. 62, pl. 67, fig. 6.
Fuligula Clangula, Ch. Bonaparte, Synopsis of Birds of United States, p.
393.
Clangula vulgaris, Common Golden-eye, Richards. and Swains. Fauna
Bor.-Amer. vol. ii. p. 456.
Common Golden-eye, Nuttall, Manual, vol ii. p. 441.

Adult Male in winter. Plate CCCXLII. Fig. 1.


Bill shorter than the head, deeper than broad at the base, gradually
depressed toward the end, which is rounded. Upper mandible with
the dorsal line straight and sloping to the middle, then slightly
concave, and finally decurved; the ridge broad and rather concave at
the base, narrowed between the nostrils, convex towards the end,
the frontal angles long, the sides erect at the base, sloping and
convex towards the end, the edges soft, with about fifty lamellæ, the
unguis oblong and decurved. Nostrils medial, linear, pervious, nearer
the ridge than the margin. Lower mandible flattened, ascending,
nearly straight, a little curved at the base, the angle long, rather
narrow, the dorsal line very slightly convex, the edges with about fifty
lamellæ, the unguis broadly elliptical.
Head large, compressed. Eyes of moderate size. Neck short and
thick. Body compact, much depressed. Feet very short, placed far
back; tarsus very short, compressed, having anteriorly in its whole
length a series of small scutella, and above the outer toe a few broad
scales, the rest covered with reticular angular scales. Hind toe very
small, with a broad free membrane beneath; anterior toes longer
than the tarsus, connected by reticulated membranes, having a sinus
on their free margins, the inner with a narrow, lobed, marginal
membrane, the outer with a thickened edge, the third and fourth
about equal and longest, all covered above with numerous narrow
scutella. Claws small, slightly arched, compressed, obtuse, that of
first toe very small, of third largest, and with an inner thin edge.
Plumage dense, soft and blended; feathers on the fore part of the
head and cheeks very small and rounded, on the upper and hind
parts, linear and elongated, as they also are on the lateral and hind
parts of the upper neck, so that when raised they give the head a
very tumid appearance, which is the more marked that the feathers
of the neck beneath are short. Wings small, decurved, pointed; the
outer primaries pointed, the first generally longest, the second
slightly shorter, in some specimens a little longer, the rest rapidly
graduated; the secondaries incurved, obliquely rounded, the inner
much elongated. Tail short, graduated, of sixteen feathers.
Bill black. Iris bright yellow. Feet orange-yellow, webs dusky, claws
black. Head and upper part of neck deep green, changing to purple
in certain lights. Back, posterior scapulars, inner secondaries, edge
of wing, alula, primary coverts, primary quills, and four or five outer
secondaries, black,—the back being darker and glossy, the wing-
feathers tinged with brown. An elliptical patch between the base of
the bill and the eye, lower part of neck all round, sides of the body
anteriorly, the lower parts generally, the scapulars, excepting their
margins, which are black, a large patch on the wing, including many
of the smaller coverts, some of the secondary coverts, and six or
seven of the secondary quills, pure white. The basal part of the
secondary coverts black. Axillar feathers and lower wing-coverts
dusky; the elongated feathers of the sides have the inner, some of
them also their outer margins black, that colour in those of the
innermost covering the whole inner web. The feathers on the legs,
and along the sides of the rump dusky. The tail brownish-grey.
Length to end of tail 20 inches, to end of wings 17 1/2, to end of
claws 20 1/4; extent of wings 31 1/2; bill along the ridge 1 5/8, from the
angles 2, along the edge of lower mandible 2 3/12; wing from flexure
9; tail 4 1/2; tarsus 1 5/12; hind toe 6 1/2/12, its claw 2 1/2/12; second toe
1 9/12, its claw 3 1/2/12; third toe 2 1/4, its claw 4 1/2/12; fourth toe 2 4/12,
its claw 3/12. Weight 2 lb. 4 1/2 oz.
Of another male, length to end of tail 19 1/2, to end of claws 21 1/2, to
end of wings 17; extent of wings 31.
Adult Female. Plate CCCXLII. Fig. 2.
The female is much smaller. Bill dusky, a portion at the end, not
however including the unguis, dull yellowish-orange. Eyes and feet
as in the male. Head and upper part of neck dull reddish-brown.
Lower part of neck and the sides of the body brownish-grey, the
feathers margined with pale grey. Upper parts greyish-brown, much
darker behind; tail brownish-grey; wings brownish-black, seven of
their coverts, excepting at the bases, white, the smaller coverts
lighter and tipped with greyish-white; the legs and sides of the rump
greyish-brown.
Length to end of tail 16 inches, to end of wings 15, to end of claws
17 1/4; extent of wings 28; wing from flexure 8 1/2; tail 3 1/4; bill along
the ridge 1 3/8, from the angles 1 3/4, along the lower mandible
1/ 1/ 1/ 1/
15 /8; tarsus 1 3
2 /8; hind toe 5/8, its claw 1
2 /8; middle toe 2 2
2 /8,
2

its claw 3/8; outer toe 1/8 longer; inner toe and claw 2. Weight 1 3/4 lb.

An adult male examined. The tongue is 2 inches long, fleshy,


papillate at the base, with two series of lateral filaments, a deep
median groove, and a thin semicircular tip, as in many other ducks.
The œsophagus is 10 inches long, of moderate diameter, dilated
towards the lower part of the neck to 1/2 inch; its walls very thick; the
proventriculus with numerous oblong glandules. The stomach is a
large and powerful gizzard, of a roundish form, 2 inches long, and of
equal diameter, its lateral muscles very large, and upwards of half an
inch thick; its epithelium rugous. The intestine is 6 feet 1 inch long,
its diameter varying from 5 twelfths to 4 twelfths; the rectum 4 inches
long; the cœca 3 1/4 inches in length, their greatest diameter 2 1/2
twelfths. The contents of the stomach a soft mass of a reddish
colour, in which are distinguished small mussels and remains of
fishes, with some vegetable fibres.
The trachea is 9 inches long, for 4 inches narrow, its diameter being
about 4 1/2 twelfths, and its rings, which are 60 in number,
cartilaginous; it then forms an ovato-oblong expansion, which, when
drawn out, is 2 1/2 inches long, and 1 inch in breadth, and is formed
of ossified and flattened rings, narrower behind, placed obliquely,
and about 30 in number; it then contracts to a diameter of 5 twelfths,
and has 16 free rings, but below this the rings, 25 in number,
become united or blended, and gradually expand into a vast irregular
cavity, having a broad bony frame in front, membranous behind, and
separating to the distance of 1 inch, the bronchi, which are large, the
right one much larger and longer than the left, and composed of 20
rings, all of which are almost complete and cartilaginous, excepting
the two upper. The rings of the left bronchus, also about 20, are
more incomplete.
Now for conjectures. These enormous dilatations are intended for
strengthening the voice. But the voice is not strong in this duck. Well,
then, they are receptacles of air, to enable the bird to keep longer
under water. But the bird does not keep longer under water than
many other ducks, and besides, the female, which has no such
dilatations, dives as well as the male.
One use at least is this. A comparison of the windpipe of an
American Golden-eye, with those of two Scotch ones, shews that the
so-called Clangula Americana, is in this respect precisely similar to
the Clangula chrysophthalma. Their digestive organs are also the
same; and American skins compared with European skins, exhibit no
differences of the slightest importance. Some individuals, especially
males, have much larger bills than others, but this happens in the
birds of both countries, and the Golden-eye is not singular in this
respect. Clangula Americana, therefore, requires a better elucidation
than the appendage of a “Nob,” before it can be admitted as a
species.
RUDDY DUCK.

Fuligula rubida, Bonap.


PLATE CCCXLIII. Male, Female, and Young.

Look at this plate, Reader, and tell me whether you ever saw a
greater difference between young and old, or between male and
female, than is apparent here. You see a fine old male in the livery of
the breeding season, put on as it were expressly for the purpose of
pleasing the female for a while. The female has never been figured
before; nor, I believe, has any representation been given of the
young in the autumnal plumage. Besides these, you have here the
young male at the approach of spring.
The Ruddy Duck is by no means a rare species in the United States;
indeed I consider it quite abundant, especially during the winter
months, in the Peninsula of Florida, where I have shot upwards of
forty in one morning. In our Eastern Districts they make their
appearance early in September, and are then plentiful from Eastport
to Boston, in the markets of which, as well as of New York, I have
seen them. On the Ohio and Mississippi they arrive about the same
period; and I have no doubt that they will be found breeding in all our
Western Territories, as soon as attention is paid to such matters as
the searching for nests with the view of promoting science, or of
domesticating birds which might prove advantageous to the
husbandman.
My friend Dr Bachman informs me that this species is becoming
more abundant every winter in South Carolina. In the month of
February he has seen a space of the extent of an acre covered with
it. Yet he has never found one in full summer plumage in that
country. It is equally fond of salt or brackish and of fresh waters; and
thus we find it at times on our sea-coast, bays, and mouths of rivers,
as well as on lakes and even small ponds in the interior, or on our
salt marshes, provided they are not surrounded by trees, as it cannot
rise high in the air unless in an open space of considerable extent. At
the time of their arrival, they are seen in small flocks, more than from
seven to ten being seldom found together, until they reach the
Southern States, where they congregate in great flocks. When they
leave their northern breeding-grounds, some proceed along the
coast, but a greater number along our numerous rivers.
The flight of the Ruddy Duck is rapid, with a whirring sound,
occasioned by the concave form of the wings and their somewhat
broad ends, the whistling sound produced by other species having
more pointed and stiffer quills, not being heard in this, or only in a
very slight degree. They rise from the water, with considerable
difficulty, being obliged to assist themselves with their broad webbed
feet, and to run as it were on the surface for several yards, always
against the breeze, when it blows smartly. The strength of the
muscles of their feet enables them to spring from the ground at once.
When they are fairly on wing, they fly in the same manner as most of
our travelling ducks, sustain themselves with ease, and are apt to
remove to great distances. They alight on the water more heavily
than most others that are not equally flattened and short in the body;
but they move on that element with ease and grace, swimming
deeply immersed, and procuring their food altogether by diving, at
which they are extremely expert. They are generally disposed to
keep under the lee of shores on all occasions. When swimming
without suspicion of danger, they carry the tail elevated almost
perpendicularly, and float lightly on the water; but as soon as they
are alarmed, they immediately sink deeper, in the manner of the
Anhinga, Grebes, and Cormorants, sometimes going out of sight
without leaving a ripple on the water. On small ponds they often dive
and conceal themselves among the grass along the shore, rather
than attempt to escape by flying, to accomplish which with certainty
they would require a large open space. I saw this very often when on
the plantation of General Hernandez in East Florida. If wounded,
they dived and hid in the grass; but, as the ponds there were
shallow, and had the bottom rather firm, I often waded out and
pursued them. Then it was that I saw the curious manner in which
they used their tail when swimming, employing it now as a rudder,
and again with a vertical motion; the wings being also slightly
opened, and brought into action as well as the feet. They are by no
means shy, for I have often waded toward them with my gun until
very near them, when I cared not about shooting them, but was on
the look-out for a new Rail or Gallinule, along the margin of the
ponds. They are often seen in company with Teals, Scaup Ducks,
Gadwalls, Shovellers, and Mallards, with all of which they seem to
agree.
My opinion that the males of this species lose the brightness of their
spring dress before they return to us in autumn, is founded on the
occurrence of multitudes of males at that season destitute of the
garb in question, and my examination of many for the purpose of
determining their sex and ascertaining that they were old birds. In
February 1832, I saw immense flocks of Ruddy Ducks about an
hundred miles up the St John’s in Florida. They would start from the
water, as our schooner advanced under sail, patting it with their feet,
so as to make a curious and rather loud noise, somewhat resembling
the fall of hail-stones on the shingles. Their notes are uttered in a
rather low tone and very closely resemble those of the female
Mallard. They afford good eating when fat and young, and especially
when they have been feeding for some weeks on fresh waters,
where their food generally consists of the roots and blades of such
grasses as spring from the bottom of rivers and ponds, as well as of
the seeds of many gramineæ. When on salt marshes, they eat small
univalve shells, fiddlers, and young crabs, and on the sea-coast,
they devour fry of various sorts. Along with their food, they swallow
great quantities of sand or gravel.
At St Augustine, in Florida, I shot a young bird of this species
immediately under the walls of the fort. Although wounded severely
and with one of its legs broken close to the body, it dived at once. My
Newfoundland dog leaped into the water, and on reaching the spot
where the bird had disappeared, dived also, and in a few moments
came up with the poor thing in his mouth. When the dog approached
I observed that the duck had seized his nose with its bill; and when I
laid hold of it, it tried to bite me also. I have found this species hard
to kill, and when wounded very tenacious of life, swimming and
diving at times to the last gasp.
In the Fauna Boreali-Americana, the tail of the Ruddy Duck is said to
be composed of sixteen feathers, and in Nuttall’s Manual of
twenty; but the number is eighteen.

Ruddy Duck, Anas rubida, Wils. Amer. Ornith. vol. viii. p. 137, pl. 71, fig. 5.
male; pl. 130, fig. 6. young male.
Fuligula rubida, Ch. Bonaparte, Synopsis of Birds of United States, p. 390.
Fuligula rubida, Ruddy Duck, Richards. and Swains. Fauna Bor.-Amer. vol.
ii. p. 455.
Ruddy Duck, Nuttall, Manual, vol. ii. p. 426.

Adult Male in summer. Plate CCCXLIII. Fig. 1.


Bill as long as the head, a little higher than broad at the base,
depressed and widened toward the end, which is rounded. Dorsal

You might also like