【GASアセンブラ】わかりにくい文法や豆知識を自分なりにまとめておく
・バイナリに特定のデータを詰め込む
.skip n(, fill)
.space n(, fill)
・文字列をバイナリに埋め込む
.ascii "abc" (nullターミネートなし)
.asciz "abc" (nullターミネートあり)
.string "abc" (nullターミネートあり)
・三つのオペランドを指定する
a(b, c, d) = a + b + c * d
-4(%eax, %ebx, %ecx) = -4 + eax + ebx * ecx
・即値の部分に文字リテラルを使用する
movb $'a, %al (0x61)
movb $' , %al (0x20)
movb $'\n, %al (0x0a)
・.textや.dataなどの意味
.textと書かれた部分はtextセクションに置かれ、.dataと書かれた部分は.dataセクションに置かれる
実際にreadelf -aで比べたので間違いない
・.code32や.code64の意味
x86とx64では機械語の解釈が異なるので、それをはじめに指定する必要がある。
・mov命令について勘違いしていたところ
movbやmovw命令では、それぞれ下から8, 16bitしか変更されない。
つまり、movb $0, %alではeaxが0になっているとは限らないのでxorl %eax, %eaxなどをする必要がある。
・ディレクションフラグ(DF)
DF = 0の時、ストリング命令でESI・EDIが増加 (CLD)
DF = 1の時、ストリング命令でESI・EDIが減少 (STD)
・ラベルをレジスタに代入する
movl rabel, regではなく、movl $rabel, regとする必要がある
・アセンブリ関数の作り方のこつ
mystrlen:
pushl %ebp
movl %esp, %ebpmystrlen_start:
movl 0x8(%ebp), %eax
xorl %ecx, %ecx
mystrlen_loop:
cmpb $0, (%eax)
je mystrlen_end
incl %eax
incl %ecx
jmp mystrlen_loop
mystrlen_end:
movl %ecx, %eax
leave
ret
といった風に、コンテキストを作っているところ、初期化をしているところ、実際の処理をしているところ、関数の終わりなどに分けて考えるとわかりやすい。
・レジスタ退避命令の特殊な奴
pushal・popalで一般レジスタの全操作
pushf・popfでフラグレジスタの操作
・割り算命令の闇