11.3. System Calls

11.3.1. Default Calling Convention

By default, the FreeBSD kernel uses the C calling
convention. Further, although the kernel is accessed
using int 80h,
it is assumed the program will call a function that
issues int 80h, rather than
issuing int 80h directly.

This convention is very convenient, and quite superior to the
Microsoft® convention used by MS-DOS®.
Why? Because the UNIX® convention allows any program written in
any language to access the kernel.

An assembly language program can do that as well.
For example, we could open a file:

This is a very clean and portable way of coding. If you need to
port the code to a UNIX® system which uses a different interrupt,
or a different way of passing parameters, all you need to change
is the kernel procedure.

But assembly language programmers like to shave off cycles. The above example
requires a call/ret combination.
We can eliminate it by
pushing an extra dword:

The 5 that we have placed in
EAX identifies
the kernel function, in this case open.

11.3.2. Alternate Calling Convention

FreeBSD is an extremely flexible system. It offers other ways of
calling the kernel. For it to work, however, the system must
have Linux emulation installed.

Linux is a UNIX® like system. However, its kernel uses the same
system-call convention of passing parameters in registers
MS-DOS® does. As with the UNIX® convention,
the function number is placed in EAX.
The parameters, however, are not passed on the stack but in
EBX, ECX, EDX, ESI, EDI, EBP:

open:
mov eax, 5
mov ebx, path
mov ecx, flags
mov edx, mode
int 80h

This convention has a great disadvantage over
the UNIX® way, at least as far as assembly language programming
is concerned: Every time you make a kernel call
you must push the registers, then
pop them later. This makes your code
bulkier and slower. Nevertheless, FreeBSD gives
you a choice.

If you do choose the Linux convention, you must let
the system know about it. After your program is assembled and
linked, you need to brand the executable:

%brandelf -t Linux filename

11.3.3. Which Convention Should You Use?

If you are coding specifically for FreeBSD, you should always
use the UNIX® convention: It is faster, you can store global
variables in registers, you do not have to brand
the executable, and you do not impose the installation of
the Linux emulation package on the target system.

If you want to create portable code that can also run
on Linux, you will probably still want to give the FreeBSD
users as efficient a code as possible. I will show you
how you can accomplish that after I have explained the basics.

11.3.4. Call Numbers

To tell the kernel which system service you are calling,
place its number in EAX. Of course, you need
to know what the number is.

11.3.4.1. The syscalls File

The numbers are listed in syscalls.
locate syscalls finds this file
in several different formats, all produced automatically
from syscalls.master.

You can find the master file for the default UNIX® calling
convention in
/usr/src/sys/kern/syscalls.master.
If you need to use the other convention implemented
in the Linux emulation mode, read
/usr/src/sys/i386/linux/syscalls.master.

Note:

Not only do FreeBSD and Linux use different calling
conventions, they sometimes use different numbers for
the same functions.