FromNandの日記

自分的備忘録

【GASアセンブラ】わかりにくい文法や豆知識を自分なりにまとめておく

・バイナリに特定のデータを詰め込む

.skip n(, fill)

.space n(, fill)

 

・文字列をバイナリに埋め込む

.ascii "abc" (nullターミネートなし)

.asciz "abc" (nullターミネートあり)

.string "abc"  (nullターミネートあり)

https://stackoverflow.com/questions/36854078/whats-the-difference-between-the-ascii-and-the-string-assembler-directives

 

・三つのオペランドを指定する

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)

https://stackoverflow.com/questions/33246811/how-to-use-character-literals-in-gnu-gas-to-replace-numbers

 

・.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, %ebp

mystrlen_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でフラグレジスタの操作

 

・割り算命令の闇

覚えにくいので貼っておく(http://bttb.s1.valueserver.jp/wordpress/blog/2017/10/29/%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9%E3%81%A7%E5%89%B2%E3%82%8A%E7%AE%97%EF%BC%88%E9%99%A4%E7%AE%97%EF%BC%89-div%E5%91%BD%E4%BB%A4%E3%81%A8idiv%E5%91%BD%E4%BB%A4/)