Function bodies
body = {expression}expr semi
| {external} external semi
| {inline} inline string semi;
These give basic semantics to functions.
Let us consider the different forms of body.
Note that it is inline
Store away the inline string
Output it on invocation
Purpose: to call the runtime library in C
Compilation model
name correspondence with the C routine
Case is significant both in Hi and C, but this is not the case of all languages.
Pascal for instance makes case insignificant, and requires that externals where the case is significant be given a name in quotes for example:
procedure close (var f:fileptr);
external name 'pasclose';
This allows the external routine to have a different name to the internal representation of it. The allowed characters in a name in Hi are limited to the letters, that means we can not call and C routine with an _ or a digit in its name unless we were to extend the syntax for externals along the above lines.
At the headof the assembler file list all the externals as follows:
extern vconcat
extern iota
extern putChar
extern getNum
extern getChar
extern putNum
Then we can call them just as if they were declared within this file.
call vconcat
Most 32-bit C compilers share the convention used by 16-bit compilers, that the names of all global symbols (functions or data) they define are formed by prefixing an underscore to the name as it appears in the C program.
However, not all of them do: the `ELF' specification states that C symbols do not have a leading underscore on their assembly-language names.
Thus if you are producing code for Linux, which uses ELF, do not use underscores.
Some existing conventions:
The C calling convention
There is an alternative convention used in windows system calls in which case step 7 becomes :
7. Once the callee has finished processing, it restores `SP' from `BP' if it had allocated local stack space, then pops the previous value of `BP', and returns via `RETF'. It uses the form of `RETF' with an immediate parameter, giving the number of bytes taken up by the parameters on the stack. This causes the parameters to be removed from the stack as a side effect of the return instruction.
Purpose of the std call is to allow calling via call gates
these are data structures in the segment table which allow transfers between privilidge levels and between different tasks.
1. Ensure that only secure entry points in the OS can be called
2. Ensure that the stack used by the OS is invisible to user code.
The hardware knows how many parameters there are on the stack from the gate descriptor. It copies them to the new stack, typically the OS stack.
On return parameters are discarded from both stacks using the RET n, instruction which specifies the number of bytes of parameters to pop.
This ensures that even if the parameters are altered by the OS routine these altered values, and the locals of the OS routine remain invisible to the calling environment.
You dont need to handle std-calls for this project, but if you are writing a compiler that is going to call Windows System calls, you need to have this as an auxilliary calling convention.
File translated from
On