■
今日は少し gcc でアセンブリ言語(gas?)を学習。
gcc -S something.c -o something.s
でアセンブリ言語が hello.s に吐かれる。
as -o something.o something.s
でコンパイル。
gcc -o something something.o
でリンク。
objdump -d something
でバイナリから逆アセンブル。
以下のように素手でアセンブルできるコードも書ける。(コメントは # で記述)
.STR0: .string "hello" .globl main main: mov $1, %ebx #ebx=1 mov $.STR0, %ecx #ecx="hello" mov $5, %edx #edx=5 mov $4, %eax #sys_write(ebx,ecx,edx) int $0x80 #exec sys_write(ebx,ecx,edx) mov $0, %ebx #ebx=0 mov $1, %eax #sys_exit(ebx) int $0x80 #exec sys_exit(ebx)
eaxに数値を代入することにより使用できるシステムコールは /usr/include/asm/unistd.h(i386 の場合、/usr/include/asm-i386/unistd.h)から参照できる。
例えば、i386 環境で「mov $4, %eax」は /usr/include/asm/unistd.h の 4 に相当するもの、つまり sys_write になる。
sys_write の引数は第1引数から順に ebx,ecx,edx と割り当たっている。
「int $0x80」で eax に入れたシステムコールが実行される。
manual は「man 2 write」のように「sys_write」から「sys_」を取り除いて man コマンドを実行して参照可能。
nasm の本は沢山存在するけど、gas の情報ってどこにあるんでしょ。