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...