|
投稿日: 2024-06-24 (月)
|
| 目次▼ |
※この記事は素人の私がコンパイルをしてアセンブリ言語を解読するだけです。間違えてたらコメ欄で指摘してくださると助かります。
これは別の記事で紹介しますたぶん
「test.c」として保存した
#include <stdio.h>
int main(void) {
int a = 5;
int b = 2;
a -= 1;
b *= 2;
int c = a + b;
printf("%d", c);
return 0;
}
コマンドプロンプトなどで以下のコマンドを実行した。
gcc -S test.c
test.c が入っているフォルダに test.s が生成されていた。
.file "test.c" .text .def __main; .scl 2; .type 32; .endef .section .rdata,"dr" .LC0: .ascii "%d\0" .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: pushq %rbp .seh_pushreg %rbp movq %rsp, %rbp .seh_setframe %rbp, 0 subq $48, %rsp .seh_stackalloc 48 .seh_endprologue call __main movl $5, -4(%rbp) movl $2, -8(%rbp) subl $1, -4(%rbp) sall -8(%rbp) movl -4(%rbp), %edx movl -8(%rbp), %eax addl %edx, %eax movl %eax, -12(%rbp) movl -12(%rbp), %eax movl %eax, %edx leaq .LC0(%rip), %rcx call printf movl $0, %eax addq $48, %rsp popq %rbp ret .seh_endproc .ident "GCC: (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project) 8.1.0" .def printf; .scl 2; .type 32; .endef
これを解読していく。
| 命令名 | 意味 | 備考 |
|---|---|---|
| mov | 代入 | mov 値 代入先 |
| add | 加算 | add 数値 加算先 |
| sub | 減算 | sub 数値 減算先 |
| imul | 乗算 | imul 数値 乗算先 |
| idiv | 除算 | idiv 数値 除算先 |
| sal | 左シフト(2倍) | sal シフト先 |
| call | 関数呼び出し | call 関数名 |
| ret | 返る | 呼び出された前の処理の位置に戻る |
$(数値)は10進数の数字(普段使う数字)です。
つまり、$6 は 6 ということになります。
※2倍のときはimulではなくsalが使われるので注意
上記の各命令の説明と照らし合わせて紐解きます。
LC0はprintの引数のラベルのようです
.LC0: .ascii "%d\0" .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main
main: は main関数の中身となっている
前処理は省いて実際にmainの処理だけに注目してみた
# レジスタ-4に5を代入(a = 5) movl $5, -4(%rbp) # レジスタ-8に2を代入(b = 2) movl $2, -8(%rbp) # レジスタ-4から1を減算(a -= 1) subl $1, -4(%rbp) # レジスタ-8の値を左にシフト(b *= 2) sall -8(%rbp) # edxにレジスタ-4の値を代入 movl -4(%rbp), %edx # eaxにレジスタ-8の値を代入 movl -8(%rbp), %eax # eaxにedxの値を加算(a + b) addl %edx, %eax # eaxの値をレジスタ-12に代入(c = 加算結果) movl %eax, -12(%rbp) # レジスタ-12の値をeaxに代入 movl -12(%rbp), %eax # eaxの値をedxに代入 movl %eax, %edx leaq .LC0(%rip), %rcx call printf movl $0, %eax addq $48, %rsp popq %rbp ret
コメントはありません。 Comments/【アセンブリ言語】C言語コンパイルしてアセンブリ言語を解読していく
キーワード: C言語, プログラミング言語, コンパイラ言語, アセンブリ言語, コンパイル, アセンブラ, 解読, 読み方
| Pitan |
![]() |
| プログラミングや音MADやらが趣味 |
| Table of Contents |
[もっと見る]
[もっと見る]