たなしょのメモ

日々勉強していることをつらつらと

アセンブリを勉強してみる

普段何気なく使っているC言語コンパイルしてx86アセンブリ言語に置き換えると

どの様にソースコードが出力されるのか見てみました。

ちなみに私のLinux環境ではAT&T記法で出力されました。

●asmSample.c

int main() {
return 42;
}

 

●asmSample.s

   .file "asmSample.c"

   .file "asmSample.c"

   .text .globl main .type main, @function

main:

.LFB0:

   .cfi_startproc

   pushq %rbp

   .cfi_def_cfa_offset 16

   .cfi_offset 6, -16

   movq %rsp, %rbp

   .cfi_def_cfa_register 6

   movl $42, %eax

   popq %rbp

   .cfi_def_cfa 7, 8

   ret

   .cfi_endproc

.LFE0:

   .size main, .-main

   .ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"

   .section .note.GNU-stack,"",@progbits

 赤文字部分を掘り下げる。

.cfi_startproc

 ファンクションの開始

 

pushq %rbp

 %rbp(ベース・ポインタ)の値をレジスタに格納

.cfi_def_cfa_offset 16

 CFAのオフセットを16にしている。(どうもデバッグ用の特殊なディレクテブらしい)

movq %rsp, %rbp

 %rsp(スタック・ポインタ)に%rbpの値を格納する

movl $42, %eax

 $42に%eax(アキュムレータ)の値を格納する

popq %rbp

 スタックから値を取り出し、値を%rbpに格納する

ret

 処理を関数の呼び出し元に戻す

 .cfi_endproc

 ファンクションの終了

 

どうもデバッグ用のディレクテブは外してコンパイルをかけることができるらしいのでまた試してみます。

 

参考

qiita.com

インストラクション

いわゆる命令のことかな?

 ****q

pushqなどのqは64bitを表しているようです。
pushqpopqmovqなど64bitでの処理をする場合はqを付けます。

 ****l

movlなどのlが付くのは32bitの処理をする命令です。

 

babyron64.hatenablog.com