We all know that the x86 architecture is
bizarre. An interesting event that has happened in the last 10 years was the change of the "system call" instruction. We all remember from DOS time that we issued "int 0x21" to make a DOS system call, and "int 0x10" to make a ROM BIOS system call. Some of us has even played with the linux system call, "int 0x80". However, five years ago, when using a Pentium IV, someone has found out that the "int" instruction could be
half as fast in a Pentium IV than in a Pentium III. Why was that ?
Intel introduced a new system call instruction in Pentium Pro/Pentium II, called "sysenter" that was supposed to be a "Fast System Call" facility. This meant that Pentium processors had two system call instructions: one that was the fast system call and the other, the slow system call (currently, there are three system calls: "int", "sysenter" and "syscall" !!!). Linux has since migrated to new style system calls. Instead of changing the "int" logic to the "sysenter" logic, another approach was taken. A new virtual shared library was created, called "
linux gate". This library is virtual because it's like a standard .so library, but only exists in memory (do a "ldd /bin/ls" and see if your system is using "linux-gate.so.1"). Applications (like libc or other system call front-ends) may then call a simple function exported from this library, __kernel_vsyscall, and this function will "systenter", "int" or issue whatever instruction is necessary for completing the system call. So here we have quick dirty "hello world" written in
NASM assembly for linux (should work on linux 2.6 for x86). The code assumes that __kernel_vsyscall is always mapped at 0xffffe400 in memory (which is wrong ;-)).
; hello.asmbits 32global _startsection .data linux_gate: equ 0xffffe400 hello: db 'Hello World !', 10 hello_len: equ $-hellosection .text_start: mov eax, 4 ; write() mov ebx, 1 mov ecx, hello mov edx, hello_len call linux_gate mov eax, 1 ; _exit() mov ebx, 42 call linux_gateNotice that we are making a procedure call, not a system call. Compile it with "nasm -f elf hello.asm; ld -o hello hello.o" . :-)