================== Linker for the ULM ================== # With the calling convetions from __Session 10__ we can write complex software. # However, _complex_ not necessarily has to mean _complicated_. Programs can be # complex because they consist of many functions, and if each function is simple # enough you still can manage to understand the complete program. But often you # don't have to understand the complete program. In many cases you just want use # functions where you know _what_ they are doing and you don't care _how_ they are # doing it. And vice versa, if you care how the function is doing it's job you can # focus on that without caring about each and every use-case. This session is about organization. Complex programs can be split into separate _translation units_ that can be translated into machine code and using a linker afterwards combined to an executable. This has various advantages, translation units can be used to implement functions that deal with only a specific problems. Therefor the code of each unit is more manageable, it can be used by different programs and can be tested independently. The following picture illustrates the idea that a function `dummy` is implemented in a separate unit `dummy.s` and used by program implemented in `main.s`: ---- TIKZ ---------------------------------------------------------------------- \begin{tikzpicture} \input{flowchart.tex} \renewcommand\BoxWidth{5} \renewcommand\FlowColDist{(\BoxWidth+2.5)} \SetMargin{0}{10}{0}{3} \Compilation{2}{source file: crts0.s} \PutStatement{0}{init stack} \PutCallStatement[red!50]{1}{call function main } \PutStatement{2}{halt with return value} \AddPath{0}{1} \AddPath{1}{2} \PutAnnotation{0}{\text{Entry point}} % next flow chart column \renewcommand\FlowCol{1} \Compilation{7}{source file: main.s} \PutStatement{0}{do something} \PutLabel{0}{main} \PutCallStatement[orange!50]{1}{ call function dummy } \PutStatement{2}{do something} \PutCallStatement[blue!50]{3}{ call function foo } \PutStatement{4}{return exit code} \AddPath{0}{1} \AddPath{1}{2} \AddPath{2}{3} \AddPath{3}{4} \PutStatement{6}{do something} \PutLabel{6}{foo} \PutStatement{7}{return} \AddPath{6}{7} \DrawLocalCallPointer[blue!50]{1}{3}{1}{6} \DrawLocalReturnPointer[blue!50]{1}{3}{1}{7} \DrawCallPointer[red!50]{0}{1}{1}{0} \DrawReturnPointer[red!50]{0}{1}{1}{4} % next flow chart column \renewcommand\FlowCol{2} \Compilation{5}{source file: dummy.s} \PutStatement{0}{do something} \PutLabel{0}{dummy} \PutCallStatement[blue!50]{1}{call function foo} \PutStatement{2}{return} \AddPath{0}{1} \AddPath{1}{2} \PutStatement{4}{do something} \PutLabel{4}{foo} \PutStatement{5}{return} \AddPath{4}{5} \DrawLocalCallPointer[blue!50]{2}{1}{2}{4} \DrawLocalReturnPointer[blue!50]{2}{1}{2}{5} \renewcommand{\CallPointerPadToY}{0} \DrawCallPointer[orange!50]{1}{1}{2}{0} \DrawReturnPointer[orange!50]{1}{1}{2}{2} \end{tikzpicture} -------------------------------------------------------------------------------- In the picture you see that another translation unit __`crt0`__`.s` is used for bootstrapping code. In our case it contains code for initializing the stack, calling `main` and halting the ULM with the return value of `main`. In general it also contains code for communicating with an operating system. :links: `crt0` -> https://en.wikipedia.org/wiki/Crt0