The stack AND the Linker
Linux expects the stack pointer (RSP) to be maintained on 16-byte boundaries in memory. That means that the hexadecimal (base 16) value for RSP should end in 0. This seems to only be required for Streaming SIMD (Single Instruction Multiple Data) Extensions, a technique that allows a vector of data to be operated on by a single instruction – useful for real-time graphics. We don’t use SIMD in this tutorial, but this seems to be best practice.
Linux also expects that the base pointer (RBP) will be pushed to the stack at the beginning of a function and removed at the end. This seems to not be required, but is helpful for debuggers. Again, it seems to be best practice.
These coding practices are implemented by the gcc C compiler by default and we have implemented them in the example programs that accompany this article. What this means is that we have added a little bit of boilerplate code to the example programs. We’ve pointed this out as we encounter it.
The gcc linker understands all about linking with the glibc standard C library. It uses the gnu linker ld to do its work, but it does a lot in the background before invoking ld. There are startup and shutdown code modules that must be linked to the executable image of your program. The C library contains the label _start inside itself. The code at _start does some initialisation, calls your main function and waits for it to return. It then does some cleanup and issues the SYS_EXIT syscall. When your assembly language programs use glibc, you should link them with gcc rather than ld. The makefiles for our next assembly language programs use the gcc linker.