FrontPage>【アセンブリ言語】C言語コンパイルしてアセンブリ言語を解読していく

【アセンブリ言語】Cをコンパイルしてアセンブリを解読していく

投稿日: 2024-06-24 (月)

※この記事は素人の私がコンパイルをしてアセンブリ言語を解読するだけです。間違えてたらコメ欄で指摘してくださると助かります。

0. MinGW を入れる

これは別の記事で紹介しますたぶん

1. Cのソースを準備する

「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;
}

2. コンパイルだけをする

コマンドプロンプトなどで以下のコマンドを実行した。

gcc -S test.c

3. アセンブラファイルを開く

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

これを解読していく。

4. アセンブラファイルを解読する

基本的な各命令の説明

命令名意味備考
mov代入mov 値 代入先
add加算add 数値 加算先
sub減算sub 数値 減算先
imul乗算imul 数値 乗算先
idiv除算idiv 数値 除算先
sal左シフト(2倍)sal シフト先
call関数呼び出しcall 関数名
ret返る呼び出された前の処理の位置に戻る

$(数値)は10進数の数字(普段使う数字)です。
つまり、$6 は 6 ということになります。

※2倍のときはimulではなくsalが使われるので注意

mainの処理

上記の各命令の説明と照らし合わせて紐解きます。

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言語コンパイルしてアセンブリ言語を解読していく

お名前:
URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

キーワード: C言語, プログラミング言語, コンパイラ言語, アセンブリ言語, コンパイル, アセンブラ, 解読, 読み方

検索

 

プロフィール

Pitan
pitan_prof.png
プログラミングや音MADやらが趣味
Table of Contents

最新のページ

最新の5件
2026-05-19 2025-08-05 2025-07-10

[もっと見る]

タグ

[もっと見る]

人気のページ

人気の5件

リンク

カウンター

合計: 506
今日: 2
昨日: 1
オンライン: 2
  編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2024-06-26 (水) 17:19:52