プログラミング言語

情報システム概論 I 

                                       筑波大学 システム情報工学研究科 
                                       コンピュータサイエンス専攻, 電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/compsys1-2007/2008-01-31
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/

前回の補足

前回「オペレーティングシステム」については、上巻「第1章 UNIXって何」、 Unix Super Text 下巻「第42 章 オペレーティングシステム」、「第43章 デバ イス」参考。

オペレーティングシステムについては、3年生の専門科目「オペレーティング システム I」、「オペレーティングシステム II」、「システムプログラム」で 学ぶ。

次のものは、オペレーティング・システムの要素ではない。

ライブラリも、オペレーティング・システムの重要な要素である。 ウインドウ・システムは、オペレーティング・システムに入れてもよい。

目標

自分が書いたプログラムがプロセスとして実行されるまで、どのような要素が 働いているか理解する。 Unix Super Text 上巻「第2章 コンピュータって何」、下巻「第57章Cの使い 方」、「第65章 Javaの使い方」参考。

プログラミング言語とは

いろいろな言語

言語の分類 コンピュータ言語は、コンピュータにして欲しい動作を表現するもの。 さまざまな種類がある。シェルに対する命令も言語の一種。

言語には文法や語彙がある。

機械語

機械語、マシン語(machine language)
コンピュータのハードウェア(CPU)が解釈できる命令の列。 01の並びで表現される。 実行する時にはメモリに置かれる。 人間がメモリに01を1つひとつ入れるのはたいへん。
アセンブリ言語(assembly language)
機械語(01)の並びでプログラムを作る変りに、命令、レジスタ、メモリの 番地に「名前」を付けて、人間が読み書きしやすくしたもの。
アセンブラというプログラムを使って機械語に変換する。

write-hello.s

画面に「hello(改行)」と表示するプログラムの例。 行番号は説明用に付けたもの。実際には不用。

[write-hello.s]

#
#       write-hello.s -- 画面に hello と表示するプログラム
#
	.text
	.align 2
	.globl _main
_main:
	li	r3,1
	addis	r4,0,ha16(hellonl)
	addi	r4,0,lo16(hellonl)
	li	r5,6
	li	r0,4
	sc
	li	r0,1
	sc
hellonl:
        .byte   104
        .byte   101
        .byte   108
        .byte   108
        .byte   111
        .byte   10
実行方法。
% cc write-hello.s [←]
% ./a.out [←]
hello
% []
アセンブリ言語について詳しくは、2年生の「機械語序論」で学ぶ。 システムコールについて詳しくは、3年生の「システムプログラム」で学ぶ。

アセンブリ言語の問題点

初期のプログラミングは、機械語、または、アセンブリ言語で行われていた。

アセンブリ言語(機械語)は、機械にはわかりやすいが 人間にはわかりにくい。

高級言語

高級言語(high level language)
アセンブリ言語のように ハードウェアの構造や機能に基づいたものではなく、 人が使う言葉や概念に基づいてプログラムを書くことができるもの。
アセンブリ言語を低レベル言語と言うこともある。

Fortran

最初に開発された高級言語。1957年。 Formula Translation の略。 数式を機械語に変換する。

コンパイルとコンパイラ

コンパイル(compile)する
高級言語で書かれたプログラムを、よりハードウェアに近い他の言語に 変換すること。
コンパイラ(compiler、翻訳系)
コンパイルするためのプログラム
ソース・プログラム(source program)
コンパイラに与えるプログラム
オブジェクト・プログラム(object program)
コンパイラ(またはアセンブラ)が出力したプログラム

リンクとライブラリ

コンパイルしたオブジェクト・プログラムだけではまだ足りない。 次のものを付け足す(リンクする)して、実行可能(executable)になる。
ライブラリ
プログラムの中でも基本的なもの、よく使われるものを、 個々のプログラムから独立させて、 さまざまなプログラムで共通で使えるようにしたもの。
実行時ルーチン
オブジェクト・プログラムを実行する時に必要になるプログラム。 コンパイラは、実行時ルーチンをあてにしてして、変換する。
実行時ルーチンの例:高級言語には、掛算がある。CPUには、掛算命令がない。 コンパイラは、実行時ルーチンの掛算プログラムをあてにして、それを利用す るためようなオブジェクト・プログラムを出力する。

注意:「ライブラリ」にはいくつかの意味がある。オペレーティング・システ ムの文脈では、システムコールとライブラリを区別する。

リンク、リンケージエディット
ライブラリや実行時ルーチンをオブジェクト・プログラムに継ぎ足す
リンカ、リンケージエディタ
リンク作業を行うプログラム

ソース・プログラムからプロセスまで

図? エディタ、ソース・プログラム、コンパイラ、オブジェクト・プログラム、リンカ、実行型式、プロセス

図? ソース・プログラムらプロセスまで

ccコマンド

cc コマンド (gcc コマンド) は、単なるコンパイラではなく、アセンブラや リンカを実行する。
% cat -n today.c  [←]
     1  #define TODAY   "Monday"
     2  main()
     3  {
     4          printf("Today is %s.\n",TODAY );
     5  }
% cc today.c  [←]
% ./a.out  [←]
Today is Monday.
% []

cc -v

% cc -v today.c  [←]
% gcc -v today.c [←]
Using built-in specs.
Target: powerpc-apple-darwin8
Configured with: /private/var/tmp/gcc/gcc-5247.obj~4/src/configure --d
isable-checking -enable-werror --prefix=/usr --mandir=/share/man --ena
ble-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*
$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --build=powerpc-
apple-darwin8 --host=powerpc-apple-darwin8 --target=powerpc-apple-darw
in8
Thread model: posix
gcc version 4.0.1 (Apple Computer, Inc. build 5247)
 /usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/cc1 -quiet -v -D__DYNAMI
C__ today.c -fPIC -quiet -dumpbase today.c -auxbase today -version -o 
/var/tmp//cc1bbrh4.s
ignoring nonexistent directory "/usr/lib/gcc/powerpc-apple-darwin8/4.0
.1/../../../../powerpc-apple-darwin8/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include
 /usr/include
 /System/Library/Frameworks
 /Library/Frameworks
End of search list.
GNU C version 4.0.1 (Apple Computer, Inc. build 5247) (powerpc-apple-darwin8)
	compiled by GNU C version 4.0.1 (Apple Computer, Inc. build 5247).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 293c7bb043389dbe08b10e2d17bba0c4
today.c: In function 'main':
today.c:4: warning: incompatible implicit declaration of built-in func
tion 'printf'
 as -arch ppc -o /var/tmp//ccAQE1HQ.o /var/tmp//cc1bbrh4.s
 /usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/collect2 -dynamic -arch 
ppc -weak_reference_mismatches non-weak -o a.out -lcrt1.o /usr/lib/gcc
/powerpc-apple-darwin8/4.0.1/crt2.o -L/usr/lib/gcc/powerpc-apple-darwi
n8/4.0.1 -L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1 -L/usr/lib/gcc/pow
erpc-apple-darwin8/4.0.1/../../.. /var/tmp//ccAQE1HQ.o -lgcc -lSystemS
tubs -lSystem
% []

図? プリプロセッサ、コンパイラ、アセンブラ、リンカ

図? ccコマンドの背後で動いているプログラム

cc -E

プリプロセッサだけ動かして、結果を標準出力へ出す。
 % cat today.c[←]
 #define TODAY   "Monday"
 main()
 {
	 printf("Today is %s.\n",TODAY );
 }
 % cc -E today.c > today.i[←]
 % cat today.i[←]
 # 1 "today.c"
 # 1 ""
 # 1 ""
 # 1 "today.c"

 main()
 {
  printf("Today is %s.\n","Monday" );
 }
 % []
C言語のプリプロセッサは、C言語そのものではなく、マクロプロセッサ。
マクロ展開
定義に従い(単純な)文字列を(複雑な)文字列に置き換える
マクロプロセッサ
マクロ展開を行うプログラム
cpp コマンド(C言語のマクロプロセッサ)は、「#」で始まる行を解釈する。
 % cpp today.c[←]
 # 1 "today.c"
 # 1 ""
 # 1 ""
 # 1 "today.c"

 main()
 {
	 printf("Today is %s.\n","Monday" );
 }
 % []
 % cpp[←]
 #define apple orange[←]
 apple computer[←]
 ^D
 # 1 ""
 # 1 ""
 # 1 ""
 # 1 ""

 orange computer
 % []
Cプリプロセッサの機能 マクロを多用すると、プログラムが読みにくくなる。
% cat macro.c [←]
#include 

#define begin {
#define end }
#define ever ;;
#define OR ||

main()
begin
  int c ;
    for(ever)
    begin
        if( (c=getchar()) == 'X' OR c == EOF )
            break;
        putchar(toupper(c));
    end
end
% cc  macro.c -o macro  [←]
% ./macro  [←]
aaa[←]
AAA
X[←]
% []

cc -S

アセンブラを実行しないで、アセンブリ言語のプログラムを .s ファイルに残 す。
% cat today.c [←]
#define TODAY   "Monday"
main()
{
        printf("Today is %s.\n",TODAY );
}

% cc -S today.c [←]
today.c: In function 'main':
today.c:4: warning: incompatible implicit declaration of built-in function 'printf'
% cat today.s [←]
	.section __TEXT,__text,regular,pure_instructions
	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
	.machine ppc
	.cstring
	.align 2
LC0:
	.ascii "Today is %s.\12\0"
	.align 2
LC1:
	.ascii "Monday\0"
	.text
	.align 2
	.globl _main
_main:
	mflr r0
	stmw r30,-8(r1)
	stw r0,8(r1)
	stwu r1,-80(r1)
	mr r30,r1
	bcl 20,31,"L00000000001$pb"
"L00000000001$pb":
	mflr r31
	addis r2,r31,ha16(LC0-"L00000000001$pb")
	la r3,lo16(LC0-"L00000000001$pb")(r2)
	addis r2,r31,ha16(LC1-"L00000000001$pb")
	la r4,lo16(LC1-"L00000000001$pb")(r2)
	bl L_printf$stub
	lwz r1,0(r1)
	lwz r0,8(r1)
	mtlr r0
	lmw r30,-8(r1)
	blr
	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
	.align 5
L_printf$stub:
	.indirect_symbol _printf
	mflr r0
	bcl 20,31,"L00000000001$spb"
"L00000000001$spb":
	mflr r11
	addis r11,r11,ha16(L_printf$lazy_ptr-"L00000000001$spb")
	mtlr r0
	lwzu r12,lo16(L_printf$lazy_ptr-"L00000000001$spb")(r11)
	mtctr r12
	bctr
	.lazy_symbol_pointer
L_printf$lazy_ptr:
	.indirect_symbol _printf
	.long	dyld_stub_binding_helper
	.subsections_via_symbols
% []

cc -c

リンカを実行しないで、.o ファイルを作成した段階で止まる。
% ls today.* [←]
today.c
% cc -c today.c  [←]
% ls today.* [←]
today.c	today.o
% []

リンクの観察

リンクは、ld というプログラムで行われることが多い(下の例は、collect2)。
% cc -v today.o -o a.out [←]
Using built-in specs.
Target: powerpc-apple-darwin8
Configured with: /private/var/tmp/gcc/gcc-5247.obj~4/src/configure --d
isable-checking -enable-werror --prefix=/usr --mandir=/share/man --ena
ble-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*
$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --build=powerpc-
apple-darwin8 --host=powerpc-apple-darwin8 --target=powerpc-apple-darw
in8
Thread model: posix
gcc version 4.0.1 (Apple Computer, Inc. build 5247)
 /usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/collect2 -dynamic -arch 
ppc -weak_reference_mismatches non-weak -o a.out -lcrt1.o /usr/lib/gcc
/powerpc-apple-darwin8/4.0.1/crt2.o -L/usr/lib/gcc/powerpc-apple-darwi
n8/4.0.1 -L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1 -L/usr/lib/gcc/pow
erpc-apple-darwin8/4.0.1/../../.. today.o -lgcc -lSystemStubs -lSystem
% []

様々なライブラリら実行時ルーチンが参照されている。

逆アセンブル

アセンブラは、アセンブリ言語で記述されたプログラムを 機械語に変換する。

逆アセンブラは、機械語をアセンブリ言語に戻す。 gdb (GNU Debugger) には、逆アセンブルの機能がある。

% cc -c today.c [←]
today.c: In function 'main':
today.c:4: warning: incompatible implicit declaration of built-in function 'printf'
% ls -l today.o [←]
-rw-r--r--   1 yas  prof  812 Jan 25 23:32 today.o
% gdb today.o [←]
GNU gdb 6.1-20040303 (Apple version gdb-434) (Wed Nov  2 17:28:16 GMT 2005)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "powerpc-apple-darwin"...
warning: Can't find LC_SEGMENT.__DATA.__data section in symbol file

(gdb) x/8x main[←]
0x0 
: 0x7c0802a6 0xbfc1fff8 0x90010008 0x9421ffb0 0x10 : 0x7c3e0b78 0x429f0005 0x7fe802a6 0x3c5f0000 (gdb) x/10i main[←] 0x0
: mflr r0 0x4 : stmw r30,-8(r1) 0x8 : stw r0,8(r1) 0xc : stwu r1,-80(r1) 0x10 : mr r30,r1 0x14 : bcl- 20,4*cr7+so,0x18 0x18 : mflr r31 0x1c : addis r2,r31,0 0x20 : addi r3,r2,104 0x24 : addis r2,r31,0 (gdb) []

Lisp言語

Fortran と同時期に開発された高級言語。

以下は、Lisp の一種、Scheme での実行例。

% open "/Applications/PLT Scheme v301/DrScheme.app" [←]
% []

図? (+ 1 2 3) define print-hello

図? DrSchemeの画面(MacOSX)

Lisp (Scheme) については、2年生の科目「ソフトウェア技法」で学ぶ。

インタプリタ

インタプリタ(通訳系)
プログラム言語を(機械語に変換することなく)直接実行するプログラム
Lisp は、インタプリタで実行することが多いが、コンパイラもある。

プログラミング言語の2種類の動作方法の違い

スクリプト言語

スクリプト言語の例

プログラミング言語の分類

手続き型言語(procedural language)、命令型言語(imperative language)
命令の実行を明示的に指示する手続きを単位としてアルゴリズムを記述する。 Fortran, Pascal, C言語など。
オブジェクト指向言語
「オブジェクト」と呼ばれる小さなプログラム単位でプログラムを記述する。 「オブジェクト」は、人間(専門家)のようなもので、 「メッセージ」を交換して、仕事を進める。 オブジェクトの内部には、手続きとデータがあるが、外からは 内部がどうなっているかわからない。Java, C++, Smalltak など。
関数型プログラミング言語
ラムダ計算や項書換えなどの理論に基づき、 関数を単位としてプログラムを記述する。 「関数」とは、引数(入力)を計算して値を得るもの。 Haskell, FP, Pure Lispなど。
論理型プログラミング言語
述語論理に基づいてプログラムを述語の集まりとして記述する。 プログラムを論理式として表わされ、プログラムの実行は論理式の証明。 Prologなど。

java言語

Sun Microsystems 社によって開発されたプログラミング言語。 コンパイラとインタプリタの2つを使って動作する。
javac コマンド
コンパイラ。Java ソースプログラムを読み込み、 「Javaバイトコード」と呼ばれる中間的なプログラムに変換する。
java コマンド
「Javaバイトコード」を解釈実行する。

図? javac,java,バイトコード

図? javac コマンドと java コマンド

% cat PrintHello.java  [←]
class PrintHello
{
    public static void main(String args[])
    {
        System.out.println("hello");
    }
}
% javac PrintHello.java [←]
% ls PrintHello.* [←]
PrintHello.class  PrintHello.java
% java PrintHello [←]
hello
% []
javaコマンドは、「Javaバイトコード」を解釈実行する変りに、機械語にコン パイルして実行することもある。このコンパイラは、Just in time (JIT) コ ンパイラと呼ばれる。

Java仮想計算機

バイトコードのインタプリタは、Java仮想計算機(virtual machine)とも呼ばれる。 バイトコードは、Java仮想計算機の機械語である。

2種類の仮想計算機

Java仮想計算機を使うと、さまざまな種類ハードウェア(CPU)やオペレーティ ング・システムで共通にバイトコードが使えるようになる。

図? Pengium,Linux,PowrPC,MacOSX,Pentium,Windows,SPARC,Solaris

図? 共通のバイトコードが使える

インタプリタ(仮想計算機)の大部分は、C言語で記述されている。 インタプリタ自身は、それぞのハードウェアの機械語にコンパイルされている。

javapコマンド

javap コマンドは、逆アセンブラ(逆コンパイラ)。
% ls PrintHello.class [←]
PrintHello.class
% javap -c PrintHello [←]
Compiled from "PrintHello.java"
class PrintHello extends java.lang.Object{
PrintHello();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #3; //String hello
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

}

% []

関連科目

Java言語、オブジェクト指向については、2年生の科目「ソフトウェア構成論 」で学ぶ。3年生の科目「システムプログラム」や主専攻実験でも、Java を使 う課題がある。

PostScript言語

Adobe社により仕様が定められた言語。 ページ・プリンタで動作することを意図して設計されている。 GhostScript (gsコマンド) は、PostScript インタプリタの1つで、結果を画面に出す。 PostScript は、逆ポーランド記法(後置記法)。日本語と同じ語順。
% gs [←]
AFPL Ghostscript 8.54 (2006-05-17)
Copyright (C) 2005 artofcode LLC, Benicia, CA.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>1 2 add 3 mul =[←]
9
GS>^D[←]
1 に 2 を足し、3を掛けたものを表示。

% cat box.ps [←]
%!
newpath
20 20 moveto
20 80 lineto
80 80 lineto
80 20 lineto
closepath
stroke
showpage
% gs -g200x200 box.ps [←]
AFPL Ghostscript 8.54 (2006-05-17)
Copyright (C) 2005 artofcode LLC, Benicia, CA.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
>>showpage, press  to continue<<
[←]
GS>^D[←]
% []

図? (20,20) (80,80) の四角形の表示。

図? GhostScript による PostScript プログラムの実行(画面表示)

プログラミング言語処理系を学ぶ意義

詳しくは、3年生の「プログラム言語処理系」、「プログラム言語論」、「オー トマトンと形式言語 」などで学ぶ。
Last updated: 2008/01/30 15:26:21
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>