Derived operations
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.
expression
- setup the frame pointer (
ENTER)
- Evaluate the expression on
the main stack
- pop the stack into a return
register
- wind back the frame pointer
(LEAVE)
- return from the function
(RET)
- in the calling environment,
remove the parameters from the stack
- push the result on stack
Inline
Note that it is inline
Store away the inline string
Output it on invocation
external routines
Purpose: to call the runtime library in C
Compilation model

Requirements
- Must establish a name
correspondence with the C routine.
- Must pass parameters appropriately
- Must get results back from C
routines
name correspondence with the C routine
Issues here
- Case of the names
- allowed characters
- how are these passed in
assembler
Characters and significance
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.
2. Assembler representation
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
Underscores
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.
Calling conventions
Some existing conventions:
The C calling convention
- The caller pushes the
function's parameters on the stack, one after another, in reverse order
(right to left, so that the first argument specified to the function is pushed
last).
- The caller then executes a
near `CALL' instruction to pass control to the callee.
- The callee receives control,
and typically (although this is not actually necessary, in functions which
do not need to access their parameters) starts by saving the value of
`ESP' in `EBP' so as to be able to use `EBP' as a base pointer to find its
parameters on the stack. However, the caller was probably doing this too,
so part of the calling convention states that `EBP' must be preserved by
any C function. Hence the callee, if it is going to set up `EBP' as a
frame pointer, must push the previous value first.
- The callee may then access
its parameters relative to `EBP'. The doubleword at `[EBP]' holds the
previous value of `EBP' as it was pushed; the next doubleword, at
`[EBP+4]', holds the return address, pushed implicitly by `CALL'. The
parameters start after that, at `[EBP+8]'. The leftmost parameter of the
function, since it was pushed last, is accessible at this offset from
`EBP'; the others follow, at successively greater offsets. Thus, in a
function such as `printf' which takes a variable number of parameters, the
pushing of the parameters in reverse order means that the function knows
where to find its first parameter, which tells it the number and type of the
remaining ones.
- The callee may also wish to
decrease `ESP' further, so as to allocate space on the stack for local
variables, which will then be accessible at negative offsets from `EBP'.
- The callee, if it wishes to
return a value to the caller, should leave the value in `AL', `AX' or
`EAX' depending on the size of the value. Floating-point results are
typically returned in `ST0'.
- Once the callee has finished
processing, it restores `ESP' from `EBP' if it had allocated local stack
space, then pops the previous value of `EBP', and returns via `RET' .
- When the caller regains
control from the callee, the function parameters are still on the stack,
so it typically adds an immediate constant to `ESP' to remove them
(instead of executing a number of slow `POP' instructions). Thus, if a
function is accidentally called with the wrong number of parameters due to
a prototype mismatch, the stack will still be returned to a sensible state
since the caller, which _knows_ how many parameters it pushed, does the
removing.
STDCALL
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.
Function of call gate to
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 two stacks
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 TEX by TTH,
version 3.05.
On 28 Oct 2003, 16:00.