例. write
writeはC上では
ssize_t write(int fd, const void *buf, size_t count);
となっておりこれをアセンブラから呼ぶには
1. 引数を渡す
2. システムコール番号を設定する
3. 割り込みを掛ける
となっており具体的には以下のようになる
section .text
global _start
_start:
mov ebx, 1 ;一番目の引数にfd(ファイルディスクリプタ)1、標準出力の値をセット
mov ecx, msg ; メッセージが置いてある箇所の先頭アドレスを2番目の引数にセット
mov edx, msglen ; 書き込むメッセージの長さを3番目の引数にセット
mov eax, 4 ; writeのシステムコール番号である「4」をシステムコール設定レジスタeaxにセット
int 0x80 ; システムコールのソフトウェア割り込み「0x80」を掛ける
msg db 'hello, world', 0x0a
msglen equ $ - msg
※プログラムを終了させるためにexitを呼ぶ
mov ebx, 0 ; 1番目の引数に0をセット exit(0)
mov eax, 1 ; exitのシステムコールをセット
int 0x80
nasmの$, $$の意味
msg db 'hello, world', 0x0a
msglen equ $ - msg
の $は現在のアドレス位置
$は式を含む行の最初で、アセンブルする場所を表す。無限ループはjmp $とすればよい。
$$は現在のセクションの最初を表す。セクション内でどれくらい離れているかは$-$$とする。