汇编教程十三(系统调用syscall)


   所有系统调用及其编号(在调用int 80h之前放入EAX的值)都列在
    [root@ht6 asinstruction]# cat /usr/include/asm-generic/unistd.h 中
   
[root@ht6 asinstruction]# cat /usr/include/asm-generic/unistd.h | more
#include <asm/bitsperlong.h>
/*
 * This file contains the system call numbers, based on the
 * layout of the x86-64 architecture, which embeds the
 * pointer to the syscall in the table.
 *
 * As a basic principle, no duplication of functionality
 * should be added, e.g. we don't use lseek when llseek
 * is present. New architectures should use this file
 * and implement the less feature-full calls in user space.
 */

#ifndef __SYSCALL
#define __SYSCALL(x, y)
#endif

#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
#else
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
#endif

#ifdef __SYSCALL_COMPAT
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
#else
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
#endif

#define __NR_io_setup 0
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
.....
 下表使用的一些系统调用:

%eax名称%ebx%ecx%edx%esx%edi
1 sys_exit int - - - -
2 sys_fork struct pt_regs - - - -
3 sys_read unsigned int char * size_t - -
4 sys_write unsigned int const char * size_t - -
5 sys_open const char * int int - -
6 sys_close unsigned int - - - -


########################################################
# 使用Linux系统调用
# 将system call number放入eax register中。
# 将参数保存到系统调用中的寄存器ebx,ecx等中。
# 调用中断(int 0x80h)。
# 结果通常在eax寄存器中返回。
# 1.系统调用sys_exit的使用
# mov eax,1 ; system call number(sys_exit)
# int 0x80 ; call kernel
# 2.系统调用sys_write的使用
# mov     edx,4           ; 消息长度
# mov     ecx,msg         ; 消息写入
# mov     ebx,1           ; file descriptor (stdout)
# mov     eax,4           ; system call number (sys_write)
# int     0x80            ; call kernel
########################################################


64位汇编程序- AT&T风格例子(gcc编译)

        .global _start
        .text
_start:                    #entry point(linker(ld) needs this)
        # write(1, msg, 14)
        mov     $1, %rax                # system call number(sys_write=1)
                    # sys_write是系统调用函数,对磁盘中文件进行写操作
        mov     $1, %rdi                # file handle 1 is stdout
        mov     $msg, %rsi              # 消息写入
        mov     $14, %rdx               # 写入14个字节
        syscall                         # 调用系统call(sys_write)

        # exit(0)
        mov     $60, %rax               # 系统调用 60 退出
        xor     %rdi, 0                 # we want return code 0
        syscall                         # invoke operating system to exit
msg:
        .ascii  "系统调用 !\n"
保存为 64bit.s 执行
[root@ht6 asinstruction]# gcc -c 64bit.s &&
ld -o 64bit 64bit.o

 64位汇编程序-Intel风格例子(nasm编译)

segment .data
    msg : db "123",10 ;
    global _start
segment .text

_start:        ;入口(linker)
    mov rax,1
    mov rdi,1
    mov rsi,msg ;消息写入
    mov rdx,14  ;输出这行是必须,否则不会输出任何内容
    syscall
    mov rax,60
    mov rdi,0
    syscall
保存为 intel64.asm 执行:
[root@ht6 asinstruction]# nasm -felf64 intel64.asm && ld -o intel64 intel64.o && ./intel64

 

posted @ 2023-03-11 12:28  jinzi  阅读(3)  评论(0)    收藏  举报