x86 Assembly/Linux

x86 Assembly/Linux

Linux syscall

Linux syscall (系统调用)在 X86 汇编里有两种方式:

int $0x80h 或 "syscall" 指令。前者可以用于 X86 / X64,后者是 X64 独有的。

Registers

系统调用所需信息以及返回值保存在通用寄存器里,int $0x80h 和 syscall 两种汇编指令使用寄存器不同。

All registers, except rcx and r11 (and the return value, rax), are preserved during the syscall.

int $ox80h

Syscall number Param 1 Param 2 Param 3 Param 4 Param 5 Param 6 Return value
eax ebx ecx edx esi edi ebp eax

syscall

Syscall number Param 1 Param 2 Param 3 Param 4 Param 5 Param 6 Return value
rax rdi rsi rdx r10 r8 r9 rax

Syscall number

  • /usr/include/asm/unistd_32.h (for int $0x80h)
  • /usr/include/asm/unistd_64.h (for syscall)
#define __NR_write 1
#define __NR_exit 60

Example

Syscall signatures:

ssize_t write(int fd, const void *buf, size_t count);
void _exit(int status);

/usr/include/asm/unistd_64.h:

#define __NR_write 1
#define __NR_exit 60
#include <unistd.h>

int main(int argc, char *argv[])
{
    write(1, "Hello World\n", 12); /* write "Hello World" to stdout */
    _exit(0);                      /* exit with error code 0 (no error) */
}

使用 X64 的 "syscall" 指令

_start:
    movq $1, %rax   ; use the write syscall
    movq $1, %rdi   ; write to stdout
    movq $msg, %rsi ; use string "Hello World"
    movq $12, %rdx  ; write 12 characters
    syscall         ; make syscall

    movq $60, %rax  ; use the _exit syscall
    movq $0, %rdi   ; error code 0
    syscall         ; make syscall

Last update: 2018-07-22 02:36:59 UTC