kvisc/ka/ABI

126 lines
3.8 KiB
Plaintext
Raw Normal View History

2019-06-15 20:21:38 +02:00
# The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
#------------------------------------------------------------------------------#
1. STACK
2019-09-08 19:04:07 +02:00
Stack grows downward. 'ebp' and 'esp' are both used.
The lowest stack frame is marked by having 'ebp' = 0.
There is a 128-bytes red zone below 'esp'.
2019-06-15 20:21:38 +02:00
A function's assembly code looks like this:
label:
2019-08-21 16:57:32 +02:00
enter N*8
2019-06-15 20:21:38 +02:00
...
...
...
leave
ret
2019-06-16 12:48:30 +02:00
'N' is the number of local variables used by the function.
2019-08-21 16:57:32 +02:00
'N' may be omitted if it is zero.
2019-06-15 20:21:38 +02:00
2019-07-15 20:58:17 +02:00
The above code is equivalent to (and can be substitued by) the following:
2019-06-15 20:21:38 +02:00
label:
2019-09-08 19:04:07 +02:00
push ebp
mov ebp, esp
sub esp, N*8
2019-06-15 20:21:38 +02:00
...
...
...
2019-09-08 19:04:07 +02:00
mov esp, ebp
pop ebp
2019-06-15 20:21:38 +02:00
ret
Between the 'enter' and the 'leave', the stack looks like this:
. .
. .
. (caller's) .
|---------------|
2019-09-08 19:04:07 +02:00
| saved eip | ebp+8 esp+(N*8)+16
| saved ebp | ebp esp+(N*8)+8
| . | ebp-8 esp+(N*8) \
| . | ebp-16 esp+(N-1)*8 |
2019-07-15 20:58:17 +02:00
| . | ... | <- local
2019-09-08 19:04:07 +02:00
| . | ebp-(N-1)*8 esp+8 | variables
| . | ebp-(N*8) esp |
2019-07-15 20:58:17 +02:00
|---------------| /
2019-07-01 21:46:36 +02:00
. (red zone) .
2019-06-15 20:21:38 +02:00
. .
. .
'enter' and 'leave' can be omitted if ALL the following hold:
the function
- uses no local variables (on the stack)
2019-09-08 19:04:07 +02:00
- never uses any function that changes 'ebp' nor 'esp',
2019-06-15 20:21:38 +02:00
aside from 'call' and 'ret'
2019-06-16 14:01:58 +02:00
You can never omit 'enter' without omitting 'leave', and vice-versa.
2019-06-15 20:21:38 +02:00
#------------------------------------------------------------------------------#
2. CALLING CONVENTION
No matter whether 'enter' and 'leave' were ommited or not, the following must
hold true whenever a function is entered or exited from:
2019-09-08 19:04:07 +02:00
- 'ebp' must be 8-bytes aligned
- 'esp' must be 8-bytes aligned
2019-06-15 20:21:38 +02:00
- the DF flag must be cleared
Aside from the DF flag, a function cannot assume anything about the state
of the flags in the FLG register.
Passing parameters is done using the following registers, in that order:
2019-07-22 13:18:13 +02:00
ax0, ax1, ax2, ax3, ax4, ax5
2019-06-15 20:21:38 +02:00
2019-07-22 13:18:13 +02:00
Further parameters are passed on the stack in reverse order. The caller then
cleans the stack.
2019-06-15 20:21:38 +02:00
Return values are passed in 'rax'. If the return value does not fit
and require more registers, use the following registers, in that order:
2019-09-08 19:04:07 +02:00
eax, edx
2019-06-15 20:21:38 +02:00
2019-07-22 13:18:13 +02:00
The following registers are volatile; the caller cannot assume
that they will be left unmodified by the callee:
2019-09-08 19:04:07 +02:00
eax, ebx, ecx, edx, esi, edi, ax0, ax1, ax2, ax3, ax4, ax5
2019-06-15 20:21:38 +02:00
2019-07-22 13:18:13 +02:00
The following registers are nonvolatile; the callee must preserve them:
2019-09-08 19:04:07 +02:00
nx0, nx1, nx2, nx3, nx4, nx5, nx6, nx7, nx8
2019-06-15 20:21:38 +02:00
#------------------------------------------------------------------------------#
2019-06-17 20:59:30 +02:00
3. VARIADIC FUNCTIONS
To call a variadic function, do this:
2019-09-08 19:04:07 +02:00
sub esp, nargs * 8
mov [esp], arg0
2019-06-17 20:59:30 +02:00
...
...
...
2019-09-08 19:04:07 +02:00
mov [esp+(N*8)], argN
2019-06-17 20:59:30 +02:00
call variadic_func
2019-09-08 19:04:07 +02:00
add esp, nargs * 8
2019-06-17 20:59:30 +02:00
To the variadic function, argN can be accessed the following way:
2019-09-08 19:04:07 +02:00
mov reg, [ebp+N*8+16]
2019-06-17 20:59:30 +02:00
For instance:
2019-09-08 19:04:07 +02:00
mov eax, [ebp+16] ; arg0
mov edx, [ebp+24] ; arg1
2019-06-17 20:59:30 +02:00
It is recommended to use the reg+reg*imm16+imm16 memory format:
2019-09-08 19:04:07 +02:00
mov eax, [ebp+ecx*8+16] ; accesses arg#ecx
2019-06-17 20:59:30 +02:00
The 'va_list' type can be regarded as a pointer to the
2019-09-08 19:04:07 +02:00
variadic function's ebp+16
2019-06-17 20:59:30 +02:00
#------------------------------------------------------------------------------#
4. SPECIAL REGISTERS
2019-06-15 20:21:38 +02:00
2019-07-15 20:47:44 +02:00
(TO BE COMPLETED)
2019-06-15 20:21:38 +02:00
#------------------------------------------------------------------------------#