[コンパイラ]CPUの命令とアセンブリ

コンパイラは、構文解析、中間パス、コード生成というステージがある
コンパイラが動作するマシンのことを「ホスト」、コンパイラが出力したコードが動作するマシンのことを「ターゲット」という
ホストとターゲットが異なるコンパイラをクロスコンパイラという

### CPU
現在実行中の命令アドレスをCPU内部に保持していて、そのアドレスから命令を読み出して、そこに書かれていることを行い、そして次の命令を読み出して実行する
現在実行中のアドレスのことをプログラムカウンタ(PC)やインストラクションポインタ(IP)という
cpuが実行するプログラム形式そのもののことを機械語(machine code)という
CPUの分岐命令(branch instruction)を使うと、次の命令以外の任意のアドレスに設定することができる(ジャンプ、分岐) eg.if文やループ文など
プログラムカウンタ以外にも少数のデータ保存領域を持っており、レジスタと呼ぶ
2つのレジスタの値を使って何らかの演算を行い、結果をレジスタに書き戻すというフォーマットになっている
命令を命令セットアーキテクチャ(instruction set architecture)という
x86-64命令セットはAMD64、Intel64, x64などと呼ばれることがある
-> awsでインスタンスを作ろうとするとき “64-bit x86″と表示されるが、このx86は命令セットのこと

### アセンブラ
アセンブリは機械語にほぼそのまま1対1で対応する言語
$ objdump -d -M intel /bin/ls

/bin/ls: file format elf64-x86-64

Disassembly of section .init:

0000000000003758 <_init@@Base>:
3758: 48 83 ec 08 sub rsp,0x8
375c: 48 8b 05 7d c8 21 00 mov rax,QWORD PTR [rip+0x21c87d] # 21ffe0 <__gmon_start__>
3763: 48 85 c0 test rax,rax
3766: 74 02 je 376a <_init@@Base+0x12>
3768: ff d0 call rax
376a: 48 83 c4 08 add rsp,0x8
376e: c3 ret

——–
3758: 48 83 ec 08 sub rsp,0x8
3758はメモリのアドレス
48 83 ec 08は命令の機械語
sub rsp,0x8はアッセンブリ rspから8を引く

### Cとアセンブラ

#include <stdio.h>

int main(int argc, char** argv[]){

	return 42; // 終了コード

}

$ gcc -o test test.c
$ ./test
$ echo $?  // 終了コードは$?にセットされる
42

### アセンブリファイルの作成
アセンブリファイルの拡張子は.s

.intel_syntax noprefix
.globl main
main:
	mov rax, 42
	ret

プログラミング勉強の良いところは、後からどんどん繋がってくることだな