Coding ARM on the Raspberry Pi

Getting ahead of the class with a single Bash script

Sean Lester-Wilson
Aug 24, 2017 · 6 min read

Next week, I’ll be taking an assembly programming course that requires a Raspberry Pi. I came back home a couple days ago to my Raspberry Pi complete with this case sold by Vostrostone, this book authored by Bruce Smith, and a 32 GB microSD card. After booting Raspbian for the first time and having fun with the built-in software, I installed Vim (as opposed to Vi which is already packaged with the OS) and began following the book’s coding exercises. So far, I’m having fun!

That is, except when I have to type this into the terminal every time I want to assemble and link my code:

as -o <program name>.o <program name>.s
ld -o <destination file name> <program name>.o

Not only that, but linking multiple files together turns into something really tedious and cumbersome:

as -o part1.o part1.s
as -o part2.o part2.s
ld -o allparts part1.o part2.o

So I wrote a shell script that’ll handle all this for me! I named it _assemble.sh so that (1) it’ll be at the top of the file list, and (2) I can autocomplete the name by typing _ and then Tab. After a couple hours of learning some Linux Bash (and appreciating how Pythonic it can be), I eventually wrote this:

read -e -p "Path for assembly: " path
read -p "Target name for executable: " name
final="ld -o "$name
cd $path
for file in *.s
do
o=${file::-2}".o"
echo "Assembling "$file " ..."
as -o $o $file
final=$final" "$o
done
echo "Linking everything ..."
eval $final
echo "Done! :D"

I saved the script and typed chmod +x _assemble.sh into the terminal. This allows me to execute the script with ./_assemble.sh so long as I’m in the same directory.

It should be noted this script works best when it shares the same parent directory as the designated folder of source files. For example, _assemble.sh and my_example_folder (which contains example1.s and example2.s) are in my ARM Projects folder, and it’s in this folder that I run the script.

This rest of the post contains: (1) an outline of the script explaining what each line does, followed by (2) the simplified summation of all the pseudocode in one paragraph, and lastly (3) a conclusion on why this script is useful for my particular applications.

I highly recommend copying and pasting the script into a text editor so you can follow along with the outline. Scrolling up and down all the time can be a real pain!


Let’s unpack what this script does starting with line 1:

read -e -p "Path for assembly: " path
  1. read = read the user input
  2. -e tells the machine that endline obtains the line of input; this allows the user to autocomplete with Tab
  3. -p tells the machine to display a prompt first
  4. "Path for assembly: " = string literal of the aforementioned prompt
  5. path = variable that the input will read into

Line 1 basically says “Read the user input after displaying a prompt, making sure to allow autocomplete, and store it into variable path.”


Here’s line 2:

read -p "Target name for executable: " name

Line 2 basically says “Read the user input after displaying a prompt, and store it into variable name.”


Here’s line 3:

final="ld -o "$name
  1. final= = assign a value to variable final
  2. "ld -o "$name = string literal "ld -o" concatenated (appended) with the string value of variable name; in typical Bash: ld = load dynamically, and -o tells the machine to load an object file

Line 3 basically says “Assign final with the combined values of (1) "ld -o" and (2) the value name the user gave previously.”


Here’s line 4:

cd $path
  1. cd = change directory
  2. $ = get value from variable

Line 4 basically says “Change the file directory to what’s specified in the string variable path.”


Here’s line 5:

for file in *.s
  1. for= loop for the following number of iterations
  2. file in = store the next iterative value into variable file
  3. *.s = all files in current directory that end in the .s extension

Line 5 basically says “For each .s file in the current directory, store its name (string value) into variable file.”


Here’s line 6:

do

Line 6 basically says “Execute the following code until stated otherwise.” (This is necessary for all loops)


Here’s line 7:

o=${file::-2}".o"
  1. {} = access contents of an array; in this case, file is a string which is an array of ASCII characters
  2. file::-2 = get all contents of array file with offset 0 and length -2 (which is until the last 2 objects, or, in this case, characters); Note: another way to write this is file:0:-2 because the syntax is ${parameter:offset:length}
  3. ".o" = extension of the object file concatenated to the variable o

Line 7 basically says “Assign variable o with the string value of file replacing the ".s" with ".o".”


Here’s line 8:

echo "Assembling "$file" ..."
  1. echo = write the following to the console
  2. "Assembling "$file"..." = string literal concatenating "Assembling " and $file and "..."

Line 8 basically says “Let the user know that the currently iterated file is being assembled.”


Here’s line 9:

as -o $o $file
  1. as = assemble the following
  2. -o tells the machine to assemble an object file
  3. $o $file = in this context, a .o file named with the value of variable o from the .s file named with the value of variable file

Line 9 basically says “Assemble an object file named whatever string value o has from a source file named whatever string value file has.”


Here’s line 10:

final=$final" "$o

Line 10 basically says “Append " " and the string value of o to variable final.” (You can get the value of a variable from within the same variable, much like most high level languages)


Here’s line 11:

done

Line 11 basically says “Stop executing code inside this do block.”


Here’s line 12:

echo "Linking everything ..."

Line 12 basically says “Let the user know that assembling has finished and the object files are being linked into an executable.”


Here’s line 13:

eval $final
  1. eval = evaluate the following command
  2. $final = value of final, which at this point will contain ld -o plus all the names of the .o files

Line 13 basically says “Evaluate the command denoted by the string value of variable final.”


Finally, here’s line 14:

echo "Done! :D"

Line 14 basically says “Tell the user that the execution of the script is complete, and do so with a smile.”


With all of that out of the way, here’s a simplified summation of what the script does:

“Get the desired folder of the source files to assemble (path), and the name of what the executable will be called (name). Assign a variable (final) to store the command to be evaluated at the end. Now start working in said folder. Loop for each source file until there are none left to iterate through. In each pass of the loop, do the following: (1) assign a variable (o) to store the name of the current source file without the .s extension; (2) tell the user that the current source file will attempt to be assembled; (3) assemble the current source file into an object file named after the aforementioned variable; and (4) append the final command string with the necessary .o file, separated by a space. Once the loop is done, tell the user that the program will attempt to link everything to gather, and evaluate the final command. Finally, tell the user the program has finished executing.”


In conclusion, this script will save me so much more time with assembling, linking, compiling, and debugging my assembly code. Not only is this script, in my opinion, short and concise, but it can be used in any parent directory that contains folders of source files. The end user experience is simply specifying the folder to operate in, and the desired name of the executable file. If I were to make this even more extensible, I would probably make the script into a terminal command that I can use anywhere, but that’s a project for another day.

Overall, I’m happy with how the script turned out, and I’m glad to have gotten a head start in this upcoming assembly course.

)
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade