L3. Assembly programming in OS environment
Program in OS env
System allocates memory for code, static data, stack and loads the program as well as initialized data from file
Program starts from entry point defined in the exec file
I/O and other hardware-related operations are handled via system service calls
System does not enforce any calling convention within the program
Program is terminated by calling the appropriate OS function (exit)
Loading and starting
Executable file contains program code and initial values of static variables
System places code and data in memory and allocates memory for BSS and stack
During loading, final linking/relocation may be performed. While the program is loaded, all addresses are fixed
Execution is started according to system ABI (Application Binary Interface)
control transferred to program's entry point using jump or subroutine call
Termination via subroutine return or calling system exit function
Basic system services
Minimal operating system has 7 services:
File access:
- open, close, read, write, seek
- standard file access functions originating from Unix system
- used also for I/O device access - terminal, printer
- terminal is accessed via two streams - stdin & stdout (always open)
Sbrk - dynamic memory allocation - Returns the pointer to memory area of the requested size
Exit - program termination - argument is a return code which may be interpreted by OS shell scripts
On the labs, we'll use two architectures:
- RARS - simulated 32-bit
- x86
Assembly program under Linux - x86
Differences with regard to SPIM
we will use NASM syntax
different section names and assembler directives
different set of system services and calling convention
Linux x86 (32bit) system services
system called via INT 0x80 instruction
function ID in register EAX
arguments in registers EBX, ECX, EDX, ESI, EDI, EBP
Linux x86-64 (64-bit) system services
system called via SYSCALL instruction
function ID in register EAX
arguments in registers RDI, RSI, RDX, R10, R9, R8
Applications of assembly programming
"Pure" assembler programs have no practical use nowadys
In practice, hybrid programming is used
main program and i/o written in HLL
computational kernels and low-level routines written in asembly as routines callable from HLL
Startup modules of HLL programs are usually written in assembly
Procedure calls in assembly languages
If we don't use any external languages (i.e. hybrid programming with C) we can create our own calling convention, without any set rules
Only basic rules defined by processor architecture should be observed
- procedure call and return
- preservation of return trace
- stack balancing
If nesting level is small, different register usage scheme may be defined for every routine