#include <stdio.h>
void print_i(int i) {
printf("%d\n", i);
}
int main() {
print_i(1);
}
この辺をコンパイルしてみると、こんなのが作れます。
%rax %rbx %rcx %rdx %rdi %rsi %rsb %rbp 等の64bitのレジスタがあります。%raxはアキュムレータと呼ばれます。x86_64の呼び出し規約では関数の返り値が%raxに入れる事になっています。
引数も、6個くらいまでは、レジスタで渡すようになっています。それ以上の場合はスタックに積んで渡します。
x86の場合は呼び出し規約にも寄りますが、基本的にレジスタ数が少ないのでスタックに引数を積んで呼び出す事になります。
; プログラムのエリアの始まり
.section __TEXT,__text,regular,pure_instructions
; _print_iは他のプログラムからも見えます
.globl _print_i
; アラインのおまじない
.align 4, 0x90
; 関数の始まり
; %edi に引数が入ってくるディシディシrdi rsi rdx rcx rbx rexとかだったはず
; Cのソース書いてコンパイルしてみれば分かる
; rspがスタックポインタでマシンのスタックトップを示してます。
; rbpがベースポインタといって、関数開始時のスタックポインタの位置を保存します。
; ベースポインタから上下で、ローカル変数だったり、呼び出し元の変数だったりします。
_print_i:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
; スタックを16バイト取るおまじない
movl %edi, %eax
movl %eax, -4(%rbp)
; 引数をメモリに保存
movl -4(%rbp), %eax
; 引数をメモリから取り出し
; これ以降は可変長引数の呼び出しのゴニョゴニョ
xorb %cl, %cl
leaq L_.str(%rip), %rdx
movq %rdx, %rdi
movl %eax, %esi
movb %cl, %al
callq _printf
; ここから、スタックを元に戻すおまじない
addq $16, %rsp
popq %rbp
ret ; 関数から戻る
; ここからはメイン関数
.globl _main
.align 4, 0x90
_main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
; ここまでスタック確保
; 引数%ed1に1を入れて _print_iを呼び出し
movl $1, %eax
movl %eax, %edi
callq _print_i
; リターン値を設定する リターン値は %eaxに入るのです。
movl $0, -8(%rbp)
movl -8(%rbp), %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
; ここからスタック解放
addq $16, %rsp
popq %rbp
ret
; データ用のセクションを開始して、%d\nをラベル付きでもつ
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "%d\n"
で、この辺を理解したら、1+1をする関数を作って、アセンブラを見て見る。1-1も見てみる。1*1を、1/1をってやっていくと、それぞれに対応するアセンブラが何かがわかります。
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b; }
引数の数に寄ってどう変わるかも、書いてコンパイルすれば分かります。
int p0() { return 0; }
int p1(int a1) { return a1; }
int p2(int a1,int a2) { return a1+a2; }
int p3(int a1,int a2,int a3) { return a1+a2+a3; }
:
char,short,int,long,double,float, unsigned char, unsigned short, unsigned int, unsigned longについて、同じように足し算等を書いてみるとその他の型について理解出来るはずです。
char add(char a, char b) { return a + b; }