アセンブリの勉強をそろそろしないとまずいと感じているので、備忘録がてら書きます。
今回はLinuxのx86_64,Intel記法について勉強します。
環境構築
まずは環境構築していきます。
sudo apt update
sudo apt install nasm build-essential
nasm
はThe Netwide Assemblerの略で、「アセンブラ」と呼ばれるツールです。
人間が書いたアセンブリ言語のソースコードを、コンピュータが直接理解できるマシン語(オブジェクトコード)に変換する翻訳機の役割をする。
nasmはあくまで、翻訳を行うツール。nasmが生成したオブジェクトファイル(.o)はそれ単体で実行することができない。
build-essential
は、ソフトウェアをコンパイル(ビルド)するために最低限必要となる基本的な開発ツール群をまとめたもの。
以下のものが含まれる。
- GCC(GNU Compiler Collection): C言語やC++のコンパイラ(gcc,g++)
- Id(Linker): リンカ。GCCに含まれている。
- make: ビルド作業を自動化するツール
- 標準ライブラリ: プログラムを動かすうえで基本となる関数群
アセンブリにおいて、build-essentialが必要となるのはリンクという作業を行うためです。
nasmが作ったオブジェクトファイルはプログラムの断片に過ぎない。これを実行可能ファイルにするには、他の必要なプログラム部品と結合(リンク)する必要がある。この作業を行うのがリンカ。
実際にアセンブリコードを書いて、理解していく。
Hello, world!
最初に書くものと言ったらHello, world!ですよね!
まずは、C言語でHello, world!
#include<unistd.h>
int main(void){
write(1, "Hello, world!\n", 14);
return 0;
}
以下のコマンドで実行
gcc hello.c
./a.out
次にアセンブリでHello, world!
section .data
msg db "Hello, world!", 0xA ; メッセージと改行コード
len equ $ - msg ; メッセージの長さ
section .text
global _start
_start:
; write(1, msg, len)
mov rax, 1 ; syscall: write
mov rdi, 1 ; file descriptor: stdout
mov rsi, msg ; pointer to message
mov rdx, len ; message length
syscall
; exit(0)
mov rax, 60 ; syscall: exit
xor rdi, rdi ; return 0
syscall
以下のコマンドで実行可能ファイルを作り実行します。
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello
解説
一行づつ解説していきます。
section .data
-
section
: セクション(領域)を定義する命令。 -
.data
: データセクション。実行時に初期化済みデータ(文字列など)を格納する領域。
msg db "Hello, world!", 0xA
-
msg
: ラベル(変数名のようなもの)。あとで参照できるようにする。 -
db
: Define Byteの略。バイト列(一バイト)でデータを定義するという意味。 -
"Hello, world!"
: 文字列リテラル。ASCIIでバイト列に変換される。 -
0xA
: 16進数で10、つまりASCIIの改行文字(LF)
この一行でmsg
という名前で"Hello, world!\n"という文字データが定義される。
len equ $ - msg
-
len
: 新しい定数の名前(ラベル) -
equ
: equate(等しい)。定数定義の命令。C言語でいえば#define
に近い。 -
$
: 現在のアセンブル位置(アドレス)を表す特殊記号。 -
msg
: 上で定義した文字列の開始アドレス。
msg - $
は、今の位置(メッセージの直後)からmsgの先頭までの長さ。
つまりメッセージの長さ(バイト数)が計算できる。
section .text
実行するコードを書くセクション。
.text
はテキストセクションでCPUが実行する命令列をここに書く。
global _start
-
global
: グローバルシンボルとして定義する宣言。 -
_start
: プログラムのエントリーポイント(開始位置を指定)。C言語でいうmain
のような役割。
_start:
- ラベル。
_start
という名前でこの位置を記録。 - 上のglobalと組み合わせて、OSにここから実行せよと伝える。
mov rax, 1
-
mov
: データをレジストリやメモリにコピーする命令。 -
rax
: 64bit汎用レジスタ、ここではシステムコード番号を入れる。 -
1
: Linuxのsys_write
の番号(書き込み)。
rax = 1
という感じ。Linuxではrax
にシステムコール番号を入れるのがルール。
mov rdi, 1
-
rdi
: 64bitレジスタ。Linuxのシステムコードでは第一引数をここに入れる。 -
1
: stdout(標準出力)のファイルディスクリプタ。
標準出力に書くという意味になる。
mov rsi, msg
-
rsi
: 第二引数を格納するレジスタ。 -
msg
: 先ほど定義したメッセージの先頭アドレス。
書き出したい文字列の場所(ポインタ)をセット。
mov rdx, len
-
rdx
: 第三引数を格納するレジスタ。 -
len
: メッセージのバイト数(14)。
個のバイト数だけ書けと指示している。
syscall
-
syscall
: Linuxカーネルにシステムコールを事項する命令。 -
rax
にシステムコール番号、rdi
,rsi
,rdx
に引数を入れておくことで動く。
ここでwrite(1, msg, len)
が実行されて、文字列が表示される。
mov rax, 60
-
60
: Linuxのexit
システムコール番号。
ここで、プロセスを終了する準備をしている。
xor rdi, rdi
-
xor
: 排他的論理和(XOR)演算。ここでは小技として使われる。 -
rdi, rdi
: 自分自身とXORをすると常に0
になる。
つまりrdi = 0
と同じ。レジスタをゼロクリア。
syscall
- 再びsyscall呼び出し。
- 今度は
exit(0)
を実行して、プログラムを正常終了させる。C言語のreturn 0
。
Hello, world!を出力するだけでも内部的にはこんなことを行っている。
繰り返し処理
まずはC言語の繰り返しのコード。
今回は、Hello, world!を5回表示するプログラムです。
#include <unistd.h>
int main(){
for(int i=0; i<5; i++){
write(1, "Hello, world!\n", 14);
}
return 0;
}
次はアセンブリのコード。
section .data
msg db "Hello, world!", 0xA ; 改行付きメッセージ
len equ $ - msg ; メッセージ長(14バイト)
section .text
global _start ; Linuxのエントリポイント
_start:
mov ecx, 0 ; int i = 0
.loop:
cmp ecx, 5 ; i < 5 ?
jge .end ; i >= 5 なら終了
; write(1, msg, 14)
mov rax, 1 ; syscall番号 1: write
mov rdi, 1 ; 引数1: stdout (fd=1)
mov rsi, msg ; 引数2: 書き出す文字列のアドレス
mov rdx, len ; 引数3: 書き出す長さ
syscall ; カーネルにシステムコール発行
inc ecx ; i++
jmp .loop ; 繰り返し
.end:
; exit(0)
mov rax, 60 ; syscall番号 60: exit
xor rdi, rdi ; 引数: returnコード = 0
syscall
解説
同様に解説していく。(先に解説したものは飛ばす)
mov ecx, 0
-
ecx
: 汎用32bitレジスタ。ここではi
の代わりといて使用。 -
0
: 初期値。
int i = 0
に対応する。
.loop
ループの開始位置を示すラベル。
cmp ecx, 5
-
cmp
: 比較命令。ecx - 5
を実行し、結果をフラグに反映(ecxの値自体は変わらない)。 - この後の
jge
命令がこの擬革結果を使う。
jge .end
-
jge
: Jump if Greater or Equal(以上ならジャンプ)。 -
cmp ecx, 5
の結果を見て、ecx >= 5
なら.end
にジャンプ。
for(int i=0; i<5; i++)
の条件部分。
inc ecx
-
ecx
を1増やす。i++
に相当する。
jmp .loop
- 無条件ジャンプ。ループの先頭に戻る。
.end:
- ループを抜けたあとの終了処理のラベル。
条件分岐
ますはC言語。
#include <unistd.h>
int main() {
int a = 0, b = 0;
if (a < b) {
write(1, "a is less than b\n", 18);
} else {
write(1, "a is not less than b\n", 22);
}
return 0;
}
次にアセンブリ。
section .data
msg1 db "a is less than b\n"
len1 equ $ - msg1 ; 18バイト
msg2 db "a is not less than b\n"
len2 equ $ - msg2 ; 22バイト
section .text
global _start
_start:
mov dword [a], 0
mov dword [b], 0
mov eax, [a] ; eax = a
mov ebx, [b] ; ebx = b
cmp eax, ebx ; a < b ?
jge .else ; a >= b なら else にジャンプ
; if 部分: write(1, msg1, len1)
mov rax, 1 ; syscall write
mov rdi, 1 ; fd=1 (stdout)
mov rsi, msg1 ; 書き込み文字列
mov rdx, len1 ; 長さ
syscall
jmp .end
.else:
; else 部分: write(1, msg2, len2)
mov rax, 1 ; syscall write
mov rdi, 1 ; fd=1 (stdout)
mov rsi, msg2
mov rdx, len2
syscall
.end:
mov rax, 60 ; syscall exit
xor rdi, rdi ; return code 0
syscall
section .bss
a resd 1
b resd 1
解説
mov dword [a], 0
-
.bss
セクションの変数a
に対して、32bit(dword)サイズで値0を代入。 - 変数
a
を0で初期化。
mov dword [b], 0
- 変数
b
を0で初期化。
mov eax, [a]
- 変数
a
の値を32bitレジスタeax
に読み込む。
mov ebx, [b]
- 変数
b
の値をebx
に読み込む。
cmp eax, ebx
-
eax
とebx
の差を計算し、結果をフラグにセット。 -
cmp
は引き算はするが結果はレジスタに保存しない比較命令。
.else:
-
else
ブロックのラベル。
section .bss
初期化されていない変数を置く領域。
a resd 1
- 32bit(4バイト)の領域を一つ確保し、変数
a
に割り当てる。
b resd 1
- 変数
b
のために同じく4バイトの領域を確保。
数値を数字として出力する
まずはC言語。
#include<unistd.h>
int main() {
int a = 5;
char c = '0' + a;
write(1, &c, 1);
write(1, "\n", 1);
return 0;
}
次にアセンブリコード。
section .data
newline db 0x0A ; 改行('\n')
section .bss
c resb 1 ; char c を保持する領域(1バイト)
section .text
global _start
_start:
; int a = 5;
mov eax, 5 ; a = 5
; char c = '0' + a;
add al, '0' ; al = al + 0x30 → '5'
mov [c], al ; c に保存
; write(1, &c, 1)
mov rax, 1 ; syscall number: write
mov rdi, 1 ; stdout
mov rsi, c ; アドレス(&c)
mov rdx, 1 ; 長さ
syscall
; write(1, "\n", 1)
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; exit(0)
mov rax, 60 ; syscall: exit
xor rdi, rdi ; return code 0
syscall
解説
同様に解説していく。
c resb 1
- ラベル
c
に1バイトのみ初期化メモリ領域を確保。 -
resb
は reserve byte。
mov eax, 5
- 変数
a = 5
を表現。 - 32bitレジスタ
eax
に5を格納。
add al, '0'
-
al
はrax
の下位8ビット(一バイト)。 -
'0'
はASCIIコードである48(0x30)。 - 数値5に文字コード48を足して
'5'
のASCIIコード53(0x35)になる。 -
int
→char
に変換しているイメージ。
mov [c], al
- 一バイトの変数
c
に、先ほど求めた'5'
を保存。 -
[]
はそのアドレスの中身を意味する。
引数なしの関数
まずはC言語。
#include <unistd.h>
void hello() {
write(1, "Hello, world!\n", 14);
}
int main() {
hello();
return 0;
}
次にアセンブリ。
section .data
msg db "Hello, world!", 0xA ; 改行付きメッセージ
len equ $ - msg ; 長さ = 14
section .text
global _start
; 関数 hello
hello:
mov rax, 1 ; syscall number: write
mov rdi, 1 ; fd = 1 (stdout)
mov rsi, msg ; 出力する文字列
mov rdx, len ; 文字数
syscall
ret ; 呼び出し元に戻る
; main 関数相当(エントリポイント)
_start:
call hello ; 関数呼び出し
mov rax, 60 ; syscall: exit
xor rdi, rdi ; return code = 0
syscall
解説
特に変わったとこはcall
だけ。
call hello
-
hello
関数を呼び出す。アドレスをpushしておいて保存。
ret
- returnの略。アドレスをpopして呼び出された関数に戻る。
引数ありの関数
まずはC言語。
#include <unistd.h>
// 引数で文字列を受け取り、出力する関数
void hello(const char *msg) {
write(1, msg, 14); // "Hello, world!\n" の長さ
}
int main() {
hello("Hello, world!\n");
return 0;
}
次にアセンブリ。
section .data
msg db "Hello, world!", 0xA ; "Hello, world!\n"
len equ $ - msg ; 14バイト
section .text
global _start
;-------------------------------------
; void hello(const char *msg)
;-------------------------------------
hello:
; write(1, msg, 14)
mov rax, 1 ; syscall number: write
mov rdi, 1 ; fd = 1 (stdout)
; rsi = msg (既に第1引数で渡されている)
mov rdx, len ; length = 14
syscall
ret ; 呼び出し元に戻る
;-------------------------------------
; エントリポイント (_start)
;-------------------------------------
_start:
mov rdi, msg ; hello(msg) の引数をセット
call hello ; 関数呼び出し
; exit(0)
mov rax, 60 ; syscall: exit
xor rdi, rdi ; return code = 0
syscall
解説
mov rdi, msg
-
hello
の引数にmsgをセット。
call hello
- 引数ありで関数を呼び出す。
命令一覧
命令 | 意味 | 例 |
---|---|---|
mov dst, src |
srcからdstへデータをコピー | mov rax, rbx |
lea dst, [src] |
アドレスを計算してdstに入れる | lea rsi, [msg] |
push val |
スタックに値をプッシュ | push rax |
pop dst |
スタックから値をポップ | pop rdi |
add dst, src |
dst=dst+src | add eax, 1 |
sub dst, src |
dst=dst-src | sub ecx, 1 |
inc dst |
dstをインクリメント | inc ecx |
dec dst |
dstをデクリメント | dec dst |
mul reg |
符号付き乗算 | imul rcx |
imul reg |
符号なし乗算 | imul rcx |
div reg |
符号なし除算 | div rbx |
idiv reg |
符号付き除算 | idiv rsi |
and dst, src |
ビットAND | and eax, 0xFF |
or dst, src |
ビットOR | or rax, rbx |
xor dst, src |
ビットXOR(クリアによく使う) | xor rdi, rdi |
not dst |
ビット反転 | not eax |
cmp a, b |
比較(a - b)→ フラグセット | cmp eax, ebx |
test a, b |
AND比較(フラグのみセット) | test eax, eax |
jmp label |
無条件ジャンプ | jmp loop_start |
je label |
等しい(ZF=1) | je equal_case |
jne label |
等しくない(ZF=0) | jne not_equal |
jg label |
より大きい(signed) | jg greater |
jl label |
より小さい(signed) | jl less |
ja label |
より大きい(unsigned) | ja above |
jb label |
より小さい(unsigned) | jb below |
jge label |
以上(signed) | jge ge_case |
jle label |
以下(signed) | jle le_case |
call foo |
関数呼び出し(戻り先をpush) | call hello |
ret |
戻り先アドレスにジャンプ | ret |
mov rax, 1 |
syscall番号 1(write) | mov rax, 1 |
mov rdi, 1 |
第1引数(stdout) | mov rdi, 1 |
mov rsi, msg |
第2引数(書き込む文字列) | mov rsi, msg |
mov rdx, 14 |
第3引数(バイト数) | mov rdx, 14 |
syscall |
カーネルにシステムコール発行 | syscall |
システムコール一覧 2025/7/16追記
%rax | システムコール名 | 説明 |
---|---|---|
0 | read | ファイルディスクリプタから読み込む |
1 | write | ファイルディスクリプタへ書き込む |
2 | open | ファイルやデバイスを開く、または作成する |
3 | close | ファイルディスクリプタを閉じる |
4 | stat | ファイルの状態を取得する(シンボリックリンクを辿る) |
5 | fstat | ファイルディスクリプタで指定されたファイルの状態を取得する |
6 | lstat | ファイルの状態を取得する(シンボリックリンクを辿らない) |
7 | poll | ファイルディスクリプタの状態を監視する |
8 | lseek | ファイルディスクリプタの読み書き位置を再設定する |
9 | mmap | ファイルやデバイスをメモリにマッピングする |
10 | mprotect | メモリ領域の保護を変更する |
11 | munmap | ファイルやデバイスのメモリマッピングを解除する |
12 | brk | データセグメントのサイズを変更する |
13 | rt_sigaction | シグナルに対するアクションを設定・調査する |
14 | rt_sigprocmask | ブロックされているシグナルを調査・変更する |
15 | rt_sigreturn | シグナルハンドラから復帰する |
16 | ioctl | デバイスを制御する |
17 | pread64 | ファイルディスクリプタの指定オフセットから読み込む |
18 | pwrite64 | ファイルディスクリプタの指定オフセットへ書き込む |
19 | readv | 複数のバッファにデータを読み込む |
20 | writev | 複数のバッファからデータを書き込む |
21 | access | ファイルの存在やアクセス権を確認する |
22 | pipe | パイプを作成する |
23 | select | 同期的なI/O多重化を行う |
24 | sched_yield | 他のスレッドにCPUを譲る |
25 | mremap | メモリ領域をリサイズ・移動する |
26 | msync | ファイルにマッピングされたメモリを同期する |
27 | mincore | ページがメモリ内に存在するかどうかを調べる |
28 | madvise | カーネルにメモリ使用に関するアドバイスを与える |
29 | shmget | System V共有メモリセグメントを割り当てる |
30 | shmat | System V共有メモリセグメントをアタッチする |
31 | shmctl | System V共有メモリを制御する |
32 | dup | ファイルディスクリプタを複製する |
33 | dup2 | ファイルディスクリプタを複製する(特定のディスクリプタ番号へ) |
34 | pause | シグナルを受信するまでプロセスを一時停止する |
35 | nanosleep | 高精度な時間だけスリープする |
36 | getitimer | インターバルタイマの値を取得する |
37 | alarm | 指定時間後にSIGALRMシグナルを送るタイマーを設定する |
38 | setitimer | インターバルタイマの値を設定する |
39 | getpid | プロセスIDを取得する |
40 | sendfile | 2つのファイルディスクリプタ間でデータをコピーする |
41 | socket | 通信のためのエンドポイントを作成する |
42 | connect | ソケットを接続する |
43 | accept | ソケット接続を受け入れる |
44 | sendto | ソケットへメッセージを送信する |
45 | recvfrom | ソケットからメッセージを受信する |
46 | sendmsg | 複数のバッファからソケットへメッセージを送信する |
47 | recvmsg | ソケットからメッセージを複数のバッファへ受信する |
48 | shutdown | ソケットの送受信をシャットダウンする |
49 | bind | ソケットに名前(アドレス)を割り当てる |
50 | listen | ソケットへの接続を待ち受ける |
51 | getsockname | ソケットの現在のアドレスを取得する |
52 | getpeername | 接続されたピアソケットのアドレスを取得する |
53 | socketpair | 接続されたソケットのペアを作成する |
54 | setsockopt | ソケットのオプションを設定する |
55 | getsockopt | ソケットのオプションを取得する |
56 | clone | 新しいプロセスを作成する(スレッド作成などに使用) |
57 | fork | 新しいプロセスを作成する(子プロセス) |
58 | vfork | 新しいプロセスを作成し、execを待つ |
59 | execve | プログラムを実行する |
60 | exit | プロセスを終了する |
61 | wait4 | 特定のプロセスの状態変化を待つ |
62 | kill | プロセスにシグナルを送る |
63 | uname | システム名と情報を取得する |
64 | semget | System Vセマフォ集合のIDを取得する |
65 | semop | System Vセマフォ操作を行う |
66 | semctl | System Vセマフォを制御する |
67 | shmdt | System V共有メモリセグメントをデタッチする |
68 | msgget | System VメッセージキューのIDを取得する |
69 | msgsnd | System Vメッセージキューにメッセージを送信する |
70 | msgrcv | System Vメッセージキューからメッセージを受信する |
71 | msgctl | System Vメッセージキューを制御する |
72 | fcntl | ファイルディスクリプタを操作する |
73 | flock | ファイルにアドバイザリロックをかける・外す |
74 | fsync | ファイルの全てのメタデータとデータをディスクに同期する |
75 | fdatasync | ファイルのデータをディスクに同期する |
76 | truncate | ファイルを指定した長さに切り詰める |
77 | ftruncate | ファイルディスクリプタで指定されたファイルを切り詰める |
78 | getdents | ディレクトリのエントリを取得する |
79 | getcwd | カレントワーキングディレクトリを取得する |
80 | chdir | カレントワーキングディレクトリを変更する |
81 | fchdir | ファイルディスクリプタで指定されたディレクトリに移動する |
82 | rename | ファイルの名前を変更する・移動する |
83 | mkdir | ディレクトリを作成する |
84 | rmdir | ディレクトリを削除する |
85 | creat | ファイルを作成する(openの古い形式) |
86 | link | ファイルへの新しいハードリンクを作成する |
87 | unlink | ファイルへのリンク(名前)を削除する |
88 | symlink | ファイルへのシンボリックリンクを作成する |
89 | readlink | シンボリックリンクが指すパスを読み取る |
90 | chmod | ファイルのパーミッションを変更する |
91 | fchmod | ファイルディスクリプタで指定されたファイルのパーミッションを変更する |
92 | chown | ファイルの所有者とグループを変更する |
93 | fchown | ファイルディスクリプタで指定されたファイルの所有者を変更する |
94 | lchown | シンボリックリンク自体の所有者を変更する |
95 | umask | ファイルモード作成マスクを設定・取得する |
96 | gettimeofday | 時刻を取得する |
97 | getrlimit | リソースの制限を取得する |
98 | getrusage | リソース使用量を取得する |
99 | sysinfo | システム全体の情報を取得する |
100 | times | プロセスの時刻情報を取得する |
101 | ptrace | プロセスをトレースする |
102 | getuid | 実ユーザIDを取得する |
103 | syslog | カーネルメッセージを読み取る・制御する |
104 | getgid | 実グループIDを取得する |
105 | setuid | ユーザIDを設定する |
106 | setgid | グループIDを設定する |
107 | geteuid | 実効ユーザIDを取得する |
108 | getegid | 実効グループIDを取得する |
109 | setpgid | プロセスグループIDを設定する |
110 | getppid | 親プロセスのIDを取得する |
111 | getpgrp | プロセスグループIDを取得する |
112 | setsid | 新しいセッションを作成する |
113 | setreuid | 実ユーザIDと実効ユーザIDを設定する |
114 | setregid | 実グループIDと実効グループIDを設定する |
115 | getgroups | 補助グループIDのリストを取得する |
116 | setgroups | 補助グループIDのリストを設定する |
117 | setresuid | 実・実効・保存ユーザIDを設定する |
118 | getresuid | 実・実効・保存ユーザIDを取得する |
119 | setresgid | 実・実効・保存グループIDを設定する |
120 | getresgid | 実・実効・保存グループIDを取得する |
121 | getpgid | 特定のプロセスのプロセスグループIDを取得する |
122 | setfsuid | ファイルシステムチェック用のユーザIDを設定する |
123 | setfsgid | ファイルシステムチェック用のグループIDを設定する |
124 | getsid | セッションIDを取得する |
125 | capget | プロセスのケーパビリティを取得する |
126 | capset | プロセスのケーパビリティを設定する |
127 | rt_sigpending | ペンディング状態のシグナルを取得する |
128 | rt_sigtimedwait | シグナルを待ち受ける(タイムアウト付き) |
129 | rt_sigqueueinfo | プロセスにシグナルとデータを送信する |
130 | rt_sigsuspend | シグナルマスクを変更し、シグナルを待つ |
131 | sigaltstack | シグナル処理用の代替スタックを設定・取得する |
132 | utime | ファイルのアクセス時刻と修正時刻を変更する |
133 | mknod | 特殊ファイルまたは通常ファイルを作成する |
134 | uselib | (廃止) 共有ライブラリを使用する |
135 | personality | プロセスの実行ドメインを設定する |
136 | ustat | ファイルシステムの状態を取得する |
137 | statfs | ファイルシステムの状態を取得する |
138 | fstatfs | ファイルディスクリプタ経由でファイルシステムの状態を取得する |
139 | sysfs | ファイルシステムに関する情報を取得する |
140 | getpriority | プロセスのスケジューリング優先度を取得する |
141 | setpriority | プロセスのスケジューリング優先度を設定する |
142 | sched_setparam | プロセスのスケジューリングパラメータを設定する |
143 | sched_getparam | プロセスのスケジューリングパラメータを取得する |
144 | sched_setscheduler | プロセスのスケジューリングポリシーとパラメータを設定する |
145 | sched_getscheduler | プロセスのスケジューリングポリシーを取得する |
146 | sched_get_priority_max | スケジューリングポリシーの最大優先度を取得する |
147 | sched_get_priority_min | スケジューリングポリシーの最小優先度を取得する |
148 | sched_rr_get_interval | RRスケジューリングのタイムスライス間隔を取得する |
149 | mlock | メモリページを物理メモリにロックする |
150 | munlock | メモリページのロックを解除する |
151 | mlockall | プロセスアドレス空間全体をロックする |
152 | munlockall | プロセスアドレス空間全体のロックを解除する |
153 | vhangup | カレント端末のハングアップ |
154 | modify_ldt | ローカルディスクリプタテーブルを修正する |
155 | pivot_root | ルートファイルシステムを変更する |
156 | _sysctl | (廃止) システムパラメータを読み書きする |
157 | prctl | プロセスを操作する |
158 | arch_prctl | アーキテクチャ固有のプロセス/スレッド設定を行う |
159 | adjtimex | カーネルの時計を調整する |
160 | setrlimit | リソースの制限を設定する |
161 | chroot | ルートディレクトリを変更する |
162 | sync | ファイルシステムのバッファをディスクに書き出す |
163 | acct | プロセスアカウンティングのオン/オフを切り替える |
164 | sethostname | ホスト名を設定する |
165 | mount | ファイルシステムをマウントする |
166 | umount2 | ファイルシステムをアンマウントする |
167 | swapon | スワップ用のファイル/デバイスを追加する |
168 | swapoff | スワップ用のファイル/デバイスを無効にする |
169 | reboot | システムを再起動する |
170 | sethostid | ホストIDを設定する |
171 | setdomainname | ドメイン名を設定する |
172 | iopl | I/O特権レベルを変更する |
173 | ioperm | I/Oポートへのアクセス許可を設定する |
174 | create_module | (廃止) カーネルモジュールをロードする領域を作成する |
175 | init_module | カーネルモジュールを初期化(ロード)する |
176 | delete_module | カーネルモジュールをアンロードする |
177 | get_kernel_syms | (廃止) エクスポートされたカーネルシンボルを取得する |
178 | query_module | (廃止) カーネルモジュールに関する情報を問い合わせる |
179 | quotactl | ディスククォータを操作する |
180 | nfsservctl | (廃止) NFSデーモンを制御する |
181 | getpmsg | (未使用) STREAMSメッセージを取得する |
182 | putpmsg | (未使用) STREAMSメッセージを送信する |
183 | afs_syscall | (未使用) AFS用のシステムコール |
184 | tuxcall | (未使用) TUX (Threaded linUX web server) 用 |
185 | security | (未使用) セキュリティ関連 |
186 | gettid | スレッドIDを取得する |
187 | readahead | ファイルを先読みする |
188 | setxattr | ファイルの拡張属性を設定する |
189 | lsetxattr | シンボリックリンクの拡張属性を設定する |
190 | fsetxattr | ファイルディスクリプタ経由で拡張属性を設定する |
191 | getxattr | ファイルの拡張属性を取得する |
192 | lgetxattr | シンボリックリンクの拡張属性を取得する |
193 | fgetxattr | ファイルディスクリプタ経由で拡張属性を取得する |
194 | listxattr | ファイルの拡張属性のリストを取得する |
195 | llistxattr | シンボリックリンクの拡張属性のリストを取得する |
196 | flistxattr | ファイルディスクリプタ経由で拡張属性のリストを取得する |
197 | removexattr | ファイルの拡張属性を削除する |
198 | lremovexattr | シンボリックリンクの拡張属性を削除する |
199 | fremovexattr | ファイルディスクリプタ経由で拡張属性を削除する |
200 | tkill | 特定のスレッドにシグナルを送信する |
201 | time | エポックからの経過時間を秒単位で取得する |
202 | futex | 高速なユーザ空間でのロック機構 |
203 | sched_setaffinity | プロセスのCPUアフィニティを設定する |
204 | sched_getaffinity | プロセスのCPUアフィニティを取得する |
205 | set_thread_area | (廃止) スレッドローカルストレージ領域を設定する |
206 | io_setup | 非同期I/Oコンテキストを初期化する |
207 | io_destroy | 非同期I/Oコンテキストを破棄する |
208 | io_getevents | 非同期I/Oイベントを読み取る |
209 | io_submit | 非同期I/O操作をサブミットする |
210 | io_cancel | 非同期I/O操作をキャンセルする |
211 | get_thread_area | (廃止) スレッドローカルストレージ領域を取得する |
212 | lookup_dcookie | ディレクトリエントリのクッキーを検索する |
213 | epoll_create | epollインスタンスを作成する |
214 | epoll_ctl_old | (古い) epollインスタンスを制御する |
215 | epoll_wait_old | (古い) epollインスタンスでI/Oイベントを待つ |
216 | remap_file_pages | (廃止) ファイルの非線形マッピングを作成する |
217 | getdents64 | 64ビット版のgetdents |
218 | set_tid_address | スレッドIDがクリアされるアドレスを設定する |
219 | restart_syscall | システムコールを再開する |
220 | semtimedop | タイムアウト付きでセマフォ操作を行う |
221 | fadvise64 | ファイルのアクセスパターンについてカーネルにアドバイスする |
222 | timer_create | POSIXタイマーを作成する |
223 | timer_settime | POSIXタイマーを開始・停止する |
224 | timer_gettime | POSIXタイマーの状態を取得する |
225 | timer_getoverrun | POSIXタイマーのオーバーラン回数を取得する |
226 | timer_delete | POSIXタイマーを削除する |
227 | clock_settime | クロックの時刻を設定する |
228 | clock_gettime | クロックの時刻を取得する |
229 | clock_getres | クロックの分解能を取得する |
230 | clock_nanosleep | 高精度な絶対時刻/相対時刻までスリープする |
231 | exit_group | スレッドグループ全体を終了する |
232 | epoll_wait | epollインスタンスでI/Oイベントを待つ |
233 | epoll_ctl | epollインスタンスを制御する |
234 | tgkill | 特定のスレッドグループ内の特定のスレッドにシグナルを送信する |
235 | utimes | ファイルのアクセス時刻と修正時刻をマイクロ秒単位で変更する |
236 | vserver | (未使用) Linux-VServer用のシステムコール |
237 | mbind | メモリポリシーを設定する |
238 | set_mempolicy | デフォルトのメモリポリシーを設定する |
239 | get_mempolicy | メモリポリシーを取得する |
240 | mq_open | POSIXメッセージキューを開く |
241 | mq_unlink | POSIXメッセージキューを削除する |
242 | mq_timedsend | タイムアウト付きでメッセージを送信する |
243 | mq_timedreceive | タイムアウト付きでメッセージを受信する |
244 | mq_notify | メッセージ到着の通知を要求する |
245 | mq_getsetattr | メッセージキューの属性を取得・設定する |
246 | kexec_load | 新しいカーネルをロードして実行する |
247 | waitid | 特定の子プロセスの状態変化を待つ |
248 | add_key | カーネルのキーリングにキーを追加する |
249 | request_key | キーリングからキーを検索する |
250 | keyctl | カーネルのキー管理機能を操作する |
251 | ioprio_set | I/Oスケジューリングのクラスと優先度を設定する |
252 | ioprio_get | I/Oスケジューリングのクラスと優先度を取得する |
253 | inotify_init | inotifyインスタンスを初期化する |
254 | inotify_add_watch | inotifyインスタンスに監視対象を追加する |
255 | inotify_rm_watch | inotifyインスタンスから監視対象を削除する |
256 | migrate_pages | プロセスのページを別のノードに移動する |
257 | openat | ディレクトリのファイルディスクリプタを基準にファイルを開く |
258 | mkdirat | ディレクトリのファイルディスクリプタを基準にディレクトリを作成する |
259 | mknodat | ディレクトリのファイルディスクリプタを基準に特殊ファイルを作成する |
260 | fchownat | ディレクトリのファイルディスクリプタを基準にファイルの所有者を変更する |
261 | futimesat | ディレクトリのファイルディスクリプタを基準にファイルの時刻を変更する |
262 | newfstatat | ディレクトリのファイルディスクリプタを基準にファイルの状態を取得する |
263 | unlinkat | ディレクトリのファイルディスクリプタを基準にファイルを削除する |
264 | renameat | ディレクトリのファイルディスクリプタを基準にファイル名を変更する |
265 | linkat | ディレクトリのファイルディスクリプタを基準にハードリンクを作成する |
266 | symlinkat | ディレクトリのファイルディスクリプタを基準にシンボリックリンクを作成する |
267 | readlinkat | ディレクトリのファイルディスクリプタを基準にシンボリックリンクを読み取る |
268 | fchmodat | ディレクトリのファイルディスクリプタを基準にファイルのパーミッションを変更する |
269 | faccessat | ディレクトリのファイルディスクリプタを基準にファイルのアクセス権を確認する |
270 | pselect6 | タイムアウトとシグナルマスク付きでI/O多重化を行う |
271 | ppoll | タイムアウトとシグナルマスク付きでファイルディスクリプタの状態を監視する |
272 | unshare | プロセスが共有する実行コンテキストの一部を分離する |
273 | set_robust_list | スレッドの堅牢なfutexリストのヘッドを設定する |
274 | get_robust_list | スレッドの堅牢なfutexリストのヘッドを取得する |
275 | splice | 2つのファイルディスクリプタ間でデータを移動する |
276 | tee | 1つのパイプから別のパイプへデータを複製する |
277 | sync_file_range | ファイルの一部をディスクに同期する |
278 | vmsplice | ユーザ空間のメモリ領域からパイプへデータを移動する |
279 | move_pages | プロセスのページを特定のノードに移動する |
280 | utimensat | ファイルのタイムスタンプを変更する(高精度) |
281 | epoll_pwait | シグナルマスク付きでepollイベントを待つ |
282 | signalfd | シグナル受信用のファイルディスクリプタを作成する |
283 | timerfd_create | タイマー通知用のファイルディスクリプタを作成する |
284 | eventfd | イベント通知用のファイルディスクリプタを作成する |
285 | fallocate | ファイルの領域を事前に割り当てる |
286 | timerfd_settime | timerfdを開始・停止する |
287 | timerfd_gettime | timerfdの状態を取得する |
288 | accept4 | 接続を受け入れ、フラグを設定する |
289 | signalfd4 | フラグ付きでsignalfdを作成する |
290 | eventfd2 | フラグ付きでeventfdを作成する |
291 | epoll_create1 | フラグ付きでepollインスタンスを作成する |
292 | dup3 | フラグ付きでファイルディスクリプタを複製する |
293 | pipe2 | フラグ付きでパイプを作成する |
294 | inotify_init1 | フラグ付きでinotifyインスタンスを初期化する |
295 | preadv | 複数のバッファに指定オフセットから読み込む |
296 | pwritev | 複数のバッファから指定オフセットへ書き込む |
297 | rt_tgsigqueueinfo | 特定のスレッドにシグナルとデータを送信する |
298 | perf_event_open | パフォーマンスカウンタへのアクセスを設定する |
299 | recvmmsg | ソケットから複数のメッセージを受信する |
300 | fanotify_init | ファイルシステムイベント通知機構を初期化する |
301 | fanotify_mark | fanotifyの監視対象を設定する |
302 | prlimit64 | プロセスのリソース制限を取得・設定する |
303 | name_to_handle_at | ファイル名をファイルハンドルに変換する |
304 | open_by_handle_at | ファイルハンドルを使ってファイルを開く |
305 | clock_adjtime | 特定のクロックを調整する |
306 | syncfs | 特定のファイルシステムを同期する |
307 | sendmmsg | ソケットへ複数のメッセージを送信する |
308 | setns | プロセスを別の名前空間に参加させる |
309 | getcpu | 現在のCPUとNUMAノードを取得する |
310 | process_vm_readv | 別のプロセスのメモリから読み込む |
311 | process_vm_writev | 別のプロセスのメモリへ書き込む |
312 | kcmp | 2つのプロセスが特定のリソースを共有しているか比較する |
313 | finit_module | ファイルディスクリプタからカーネルモジュールをロードする |
314 | sched_setattr | プロセスのスケジューリング属性を設定する |
315 | sched_getattr | プロセスのスケジューリング属性を取得する |
316 | renameat2 | フラグ付きでファイル名を変更する |
317 | seccomp | セキュアコンピューティングモードを設定する |
318 | getrandom | 暗号学的に安全な乱数を取得する |
319 | memfd_create | 匿名ファイルを作成する |
320 | kexec_file_load | ファイルから新しいカーネルをロードする |
321 | bpf | BPFプログラムやマップを操作する |
322 | execveat | ディレクトリのファイルディスクリプタを基準にプログラムを実行する |
323 | userfaultfd | ユーザ空間でのページフォルト処理用のファイルディスクリプタを作成する |
324 | membarrier | メモリバリアを発行する |
325 | mlock2 | フラグ付きでメモリをロックする |
326 | copy_file_range | 2つのファイルディスクリプタ間でデータをコピーする |
327 | preadv2 | フラグ付きでpreadvを実行する |
328 | pwritev2 | フラグ付きでpwritevを実行する |
329 | pkey_mprotect | 保護キー付きでメモリの保護を変更する |
330 | pkey_alloc | 保護キーを割り当てる |
331 | pkey_free | 保護キーを解放する |
332 | statx | ファイルの状態をより詳細に取得する |
333 | io_pgetevents | ポーリング付きで非同期I/Oイベントを取得する |
334 | rseq | restartable sequence (rseq) を登録する |
424 | pidfd_send_signal | pidfd(プロセスファイルディスクリプタ)にシグナルを送る |
425 | io_uring_setup | io_uring(非同期I/O)インスタンスをセットアップする |
426 | io_uring_enter | io_uringのサブミッション/コンプリーションキューを処理する |
427 | io_uring_register | io_uringインスタンスにリソース(ファイルやバッファ)を登録する |
428 | open_tree | ファイルシステムのサブツリーを表すファイルディスクリプタを開く |
429 | move_mount | マウントポイントを移動する |
430 | fsopen | ファイルシステムを開くためのコンテキストを作成する |
431 | fsconfig | ファイルシステム作成コンテキストにパラメータを設定する |
432 | fsmount | 設定されたコンテキストからファイルシステムをマウントする |
433 | fspick | ファイルディスクリプタを元にマウントを選択する |
434 | pidfd_open | プロセスIDからpidfdを取得する |
435 | clone3 | cloneをより柔軟にしたプロセス作成インターフェース |
436 | close_range | 指定した範囲のファイルディスクリプタを閉じる |
437 | openat2 | openatの拡張版で、より詳細なオプションを指定できる |
438 | pidfd_getfd | 他のプロセスのファイルディスクリプタを安全に取得する |
439 | faccessat2 | faccessatの拡張版で、フラグを指定できる |
440 | process_madvise | 他のプロセスのメモリ使用法についてカーネルにアドバイスする |
441 | epoll_pwait2 | epoll_pwaitの拡張版(タイムアウトの精度が高い) |
442 | mount_setattr | マウントポイントの属性を変更する |
443 | quotactl_fd | ファイルディスクリプタ経由でディスククォータを操作する |
444 | landlock_create_ruleset | Landlock(サンドボックス)のルールセットを作成する |
445 | landlock_add_rule | Landlockのルールセットにルールを追加する |
446 | landlock_restrict_self | Landlockのルールセットを現在のプロセスに適用する |
447 | memfd_secret | シークレットメモリ領域(他から見えない)を作成する |
448 | process_mrelease | プロセスリリースのエージェントとして動作するよう要求する |
449 | futex_waitv | 複数のfutexを一度に待機する |
450 | set_mempolicy_home_node | メモリポリシーのホームノードを設定する |
451 | cachestat | ページのキャッシュ状態を取得する |
452 | fchmodat2 | fchmodatの拡張版で、フラグを指定できる |
453 | map_shadow_stack | シャドウスタック用のメモリをマッピングする |
454 | futex_wake | futexで待機しているタスクを起床させる (futex_waitvと対) |
455 | futex_wait | futexの値が期待通りになるまで待機する (futex_waitvと対) |
456 | futex_requeue | 1つのfutexのウェイターを別のfutexに移動する (futex_waitvと対) |
457 | statmount | マウントポイントに関する情報を取得する |
458 | listmount | マウントのリストを取得する |
459 | lsm_get_self_attr | Linux Security Module (LSM) の属性を取得する |
460 | lsm_set_self_attr | Linux Security Module (LSM) の属性を設定する |
461 | lsm_list_modules | 利用可能なLSMのリストを取得する |
462 | mseal | メモリ領域を「封印」して不変にするためのセキュリティ機能 |
463 | setxattrat | ファイルの拡張属性を設定(または作成)する |
464 | getxattrat | ファイルの拡張属性の値を取得する |
465 | listxattrat | ファイルに設定されている拡張属性のキー(名前)の一覧を取得する |
466 | removexattrat | ファイルの拡張属性を削除する |
詳しくシステムコールについて知りたい場合は、以下のサイトを参考にすると良い。
用語説明
ファイルディスクリプタ
プログラムがファイルやその他のI/Oリソース(入出力リソース)を操作するために、オペレーティングシステム(OS)が割り当てる一意の整数値のこと。
OSがファイルなどのリソースを識別・管理するための「整理番号」のようなもの。
番号を指定することで、長いファイル名を指定しなくても番号で指定できる。
カーネル
OSの脳みそにあたる最も重要なプログラム。
パソコンの電源を入れると最初に動き出し、電源を切るまでずっと動き続けている。
ユーザー空間
アプリケーション(ブラウザ、ワープロソフトなど)は、すべてこの空間で動作する。
この空間のプログラムは、使えるメモリの範囲や機能に厳しい制限がある。
カーネル空間
カーネル自身がこの空間で動作する。
コンピュータのすべてのリソース(メモリ、CPUなど)にアクセスできる、非常に高い権限を持っている。
プロセス
実行中のプログラムのこと。
各プロセスは自分電用のメモリ空間をもち、他のプロセスのメモリ空間には基本的にアクセスできない。
コンテキストスイッチ
CPUが処理する対象を、あるプロセスから別のプロセス(またはカーネル)切り替えること。
特権レベル/リングプロテウション
カーネル空間とユーザー空間の分離を、CPUがハードウェアレベルで矯正するための仕組み。
x86アーキテクチャでは、セキュリティレベルが輪(リング)のような階層で表現される。
- リング0(Kernel Mode):
最も権限が強いモード。カーネルがこのレベルで動作し、すべての命令を実行できる。 - リング3(User Mode):
最も権限が弱いモード。通常のアプリケーションはこのレベルで動作し、事項できる命令が制限されている。
syscallがこのリングを超える唯一の扉になる。
マウントポイント
ハードディスクやUSBメモリといった、あとから接続した記憶装置への入口となる既存のディレクトリ。