Building and Running Programs
Last updated
Last updated
Writing programs is not too much fun if you can't run them. But to run a program, it needs to be built first. But what does that mean?
You are writing your programs in an assembly language. Assembly language is made to be human-readable, but your CPU wouldn't know what to do with it. Thereby, it needs to be assembled (). The assembler (e.g., as
, or for clang the LLVM integrated assembler) converts the (target-specific) Assembly code into (target-specific) machine code, as so-called object files.
The assembled object files are not yet runable code. There may be calls to library functions (e.g., printf
) or use of other external symbols that need to be resolved. That is where the final step of linking comes in. The linker (e.g., GNU's ld
, LLVM's lld
) will take the object file (or object files) of your program and perform several tasks to create the final executable. Some of these tasks include resolving external symbols as mentioned before, but also assigning final memory addresses to the program's instructions and data and adjusting addresses in the machine code accordingly.
The output of the linker will be the final executable (machine-code) version of your program.
The linking process needs to know where to look for library files, which may be in a number of locations and different based on the OS. Luckily there is an easy cheat to avoid this cumbersome listing/lookup process used by almost any sane programmer: use a compiler collection like gcc
or clang
to do the work on our behalf. So to assemble and link an Assembly program the work is reduced to:
If you are interested in the underlying work performed by clang
, you can add the -v
flag and have a look at the terminal output.
It is important to know how to build your programs. However, as some of the assignments require some slightly more intricate assembling and linking options, the process is taken care of for you through a Makefile
. Put simply, this system handles all necessary steps to create a given "target".
To build any of the assignments, you simply run:
from the root folder of the framework.
You may even use the given shortcut targets:
to build and run the program in one step. The shortcut target for a1
would be equivalent to executing the following command:
Note that if you try the above-mentioned shortcut target for any of the assignment programs, initially make
will fail with an error.
This does not mean that building your program has failed. Rather, the execution of your program did not exit with code 0 (as you haven't yet implemented a proper return value) and thereby make
gives a notice that running your program has "failed".
Examining the Makefile is a great way to find and further understand the above-described concepts. However, there are many things in the file that you do not have to understand at this point.
You are free to modify the Makefile at your own risk (e.g., to add targets for specific program invocations/extra assignments/other tweaks that may help your process).
However, be advised that CodeGrade will use the Makefile as given in the framework to build your programs.