2 C コンパイラー

C 言語で書かれたプログラムをコンピューターが理解できる形式 (機械語, machine language) に翻訳するプログラムを C コンパイラー (C compiler) と呼ぶ。

(普通は単にコンパイルするだけでなく、 必要なライブラリィとリンクすることで、いわゆる実行形式のファイルを作る。)

現象数理学科 Mac では、 Apple の用意した Xcode と呼ばれるソフトウェアをインストールしてあり、 そこに Clang+LLVM のコンパイラー cc が含まれている。

現象数理学科 Mac では、 グラフィックス・ライブラリィ GLSC を利用する C プログラムのコンパイル のために cglsc コマンドというのを用意してある。 それは中から cc を呼び出しているので、 結局は Clang+LLVM を利用することになる。

cc の使い方は、 UNIX で伝統的な cc の使い方と互換性がある。 よく使うオプションなどは 「C言語で数値計算プログラミング」1.コンパイル、実行の仕方 で解説しておいた。


(脱線) アセンブリー言語に翻訳してみる     機械語はビット列なので人間には読みにくいが、 機械語とほぼ一対一に対応するアセンブリー言語という形式に変換すると、 どのような機械語に変換されるのかが(まあまあ)分かりやすい。 cc -S とすると、C言語のプログラムをアセンブリー言語に変換出来る。

アセンブリー言語のプログラムを機械語に変換することを 「アセンブルする」と言い、 アセンブルするためのプログラムをアセンブラーと呼ぶ。 実は cc はアセンブラーの機能も備えている。

以下の例では、 小さな C プログラム prog.c を、 アセンブリー言語に翻訳したプログラム prog.s を作り、 それを表示した後、 prog.s をアセンブル&リンクして実行形式 a.out を作って実行している。

(以下で bash-3.2$ はプロンプトで、 これはユーザーが入力するものではない。)
bash-3.2$ ls
prog.c
bash-3.2$ cat prog.c
#include <stdio.h>

int main(void)
{
  int a,b,c,d;
  a = 1; b = 2; c = 3;
  d = a * b + c;
  printf("%d*%d+%d=%d\n", a, b, c, d);
  return 0;
}
bash-3.2$ cc -S prog.c
bash-3.2$ ls
prog.c  prog.s
bash-3.2$ cat prog.s
(中略)
bash-3.2$ cc prog.s
bash-3.2$ ls
a.out*  prog.c  prog.s
bash-3.2$ ./a.out
1*2+3=5
bash-3.2$

次に (macOS 上の cc で作成した場合の) prog.s の内容を掲げる。 $ 1\times 2+3$ という計算をして、 printf() を呼び出しているのが分かるだろうか?

prog.s -- アセンブリ言語プログラムの例
        .section        __TEXT,__text,regular,pure_instructions
        .macosx_version_min 10, 13
        .globl  _main                   ## -- Begin function main
        .p2align        4, 0x90
_main:                                  ## @main
        .cfi_startproc
## BB#0:
        pushq   %rbp
Lcfi0:
        .cfi_def_cfa_offset 16
Lcfi1:
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
Lcfi2:
        .cfi_def_cfa_register %rbp
        subq    $32, %rsp
        leaq    L_.str(%rip), %rdi
        movl    $0, -4(%rbp)
        movl    $1, -8(%rbp)
        movl    $2, -12(%rbp)
        movl    $3, -16(%rbp)
        movl    -8(%rbp), %eax
        imull   -12(%rbp), %eax
        addl    -16(%rbp), %eax
        movl    %eax, -20(%rbp)
        movl    -8(%rbp), %esi
        movl    -12(%rbp), %edx
        movl    -16(%rbp), %ecx
        movl    -20(%rbp), %r8d
        movb    $0, %al
        callq   _printf
        xorl    %ecx, %ecx
        movl    %eax, -24(%rbp)         ## 4-byte Spill
        movl    %ecx, %eax
        addq    $32, %rsp
        popq    %rbp
        retq
        .cfi_endproc
                                        ## -- End function
        .section        __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
        .asciz  "%d*%d+%d=%d\n"


.subsections_via_symbols



桂田 祐史