細說linux系統呼叫 使用c和彙編進行系統呼叫

2021-07-14 15:21:56 字數 4072 閱讀 5770

linux系統如何列印」hello world」

使用fprintf輸出到stdout

#include 

int main(int argc, char *argv)

使用write將字串輸出到stdout_fileno

#include 

int main(int argc, char *argv)

使用glibc提供的syscall進行系統呼叫sys_write將字串輸出到stdout_fileno

#define _gnu_source         /* see feature_test_macros(7) */

#include

#include /* for sys_*** definitions */

int main(int argc, char *argv)

intel code

at&t code

mov eax,1

movl $1,%eax

mov ebx,0ffh

movl $0xff,%ebx

int 80h

int $0x80

mov ebx, eax

movl %eax, %ebx

mov eax,[ecx]

movl (%ecx),%eax

mov eax,[ebx+3]

movl 3(%ebx),%eax

mov eax,[ebx+20h]

movl 0x20(%ebx),%eax

add eax,[ebx+ecx*2h]

addl (%ebx,%ecx,0x2),%eax

lea eax,[ebx+ecx]

leal (%ebx,%ecx),%eax

sub eax,[ebx+ecx*4h-20h]

subl -0x20(%ebx,%ecx,0x4),%eax

使用nasm格式彙編進行int 80h系統呼叫,nasm_write.s內容如下

; nasm -f elf64 nasm_write.s && ld -s -o nasm_write nasm_write.o

section .data

hello db 'hello world!', 10 ; 『hello world!』加乙個換行符(10)

len equ $-hello ; 字串長度

section .text

global _start

_start:

mov eax, 4 ; 系統呼叫sys_write

mov ebx, 1 ; 檔案描述符,標準輸出

mov ecx, hello ; 設定字串偏移位址到ecx

mov edx, len ; 設定字串長度

int80h ; 中斷0x80, kernel系統呼叫syscall

mov eax, 1 ; exit的系統呼叫(sys_exit)

mov ebx, 0 ; 退出值我為0

int80h

編譯

nasm -f elf64 nasm_write.s && ld -s -o nasm_write nasm_write.o
在linux x86和linux x86_64系統上可以使用int $0x80製造中斷0x80進行系統呼叫。呼叫引數:

syscall #

param 1

param 2

param 3

param 4

param 5

param 6

eaxebx

ecxedx

esiedi

ebp

return value

eax

在arch/x86/include/asm/unistd_32.h中,exit和write的syscall number為

#define __nr_exit 1

#define __nr_write 4

at&t格式彙編通過int $0x80進行系統呼叫

# as -o gas_int.o gas_int.s && ld -s -o gas_int gas_int.o

.data # section宣告

msg: .ascii "hello world!\n"

len = . - msg # 字串長度

.text

.global _start

_start:

movl $4, %eax

movl $1, %ebx

movl $msg, %ecx

movl $len, %edx

int $0x80

movl $1, %eax

movl $0, %ebx

int $0x80

編譯:

as -o gas_int.o gas_int.s && ld -s -o gas_int gas_int.o
在x86_64上有專用指令進行系統呼叫

syscall #

param 1

param 2

param 3

param 4

param 5

param 6

raxrdi

rsirdx

r10r8r9

return value

rax

在arch/x86/include/asm/unistd_64.h中相應的syscall number

#define __nr_write 1

#define __nr_exit 60

檔案gas_syscall.s

# as -o gas_syscall.o gas_syscall.s && ld -s -o gas_syscall gas_syscall.o

.data

msg: .ascii "hello world!\n"

len = . - msg # 字串長度

.text

.global _start

_start:

movq $1, %rax

movq $1, %rdi

movq $msg, %rsi

movq $len, %rdx

syscall

movq $60, %rax

movq $0, %rdi

syscall

編譯

as -o gas_syscall.o gas_syscall.s && ld -s -o gas_syscall gas_syscall.o
gcc -nostdlib不連線glibc庫

/**

* 在c語言中內聯彙編,使用at&t風格

* 編譯: gcc -nostdlib inline.c -o inline

*//**

* @brief 通過系統呼叫列印字串

*/void my_printf(char *s, int len)

/** * @brief 程式入口

*/void _start()

參考

+ hello, world!

+ linux system call table

+ linux assembly howto 6.2. hello, world!

+ x86 assembly/inte***cing with linux

+ x86 assembly/nasm syntax

+ what is better 「int 0x80」 or 「syscall」?

+ linux c中內聯彙編的語法格式及使用方法(inline assembly in linux c)

Linux系統呼叫 使用syscall

博主的另一篇博文介紹了如何使用int 0x80指令進行linux系統呼叫,這一篇博文介紹一下如何使用另一種方式 syscall指令進行linux系統呼叫,然後會簡要說明二者的不同。通過syscall指令進行linux系統呼叫與通過int 0x80指令進行linux系統呼叫在使用上差別不大,系統呼叫號...

使用linux系統呼叫ABI

void prints char str asm movl 4,eax n t movl 1,ebx n t movl 0,ecx n t movl 1,edx n t int 0x80 n t m str m i return intmain 這裡的關鍵在於linux系統0x80號中斷是32位系統...

Linux系統呼叫和庫函式呼叫

linux下對檔案操作有兩種方式 系統呼叫 system call 和庫函式呼叫 library functions 可以參考 linux程式設計 英文原版為 beginning linux programming 作者是neil matthew和richard stones 第三章 working...