![[←]](../icons/screen-return.gif)
![[]](../icons/screen-cursor.gif)
情報システム概論 I 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~yas/coins/dsys-2005/2006-02-06
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
言語には文法や語彙がある。
1: # 2: # write-hello.s -- 画面に hello と表示するプログラム 3: # 4: .text 5: .align 2 6: .globl main 7: main: 8: movl $1, %ebx 9: movl $hellonl, %ecx 10: movl $6, %edx 11: movl $4, %eax 12: int $0x80 13: movl $1, %eax 14: int $0x80 15: 16: .data 17: .align 0 18: hellonl: 19: .byte 104 20: .byte 101 21: .byte 108 22: .byte 108 23: .byte 111 24: .byte 10
% as write-hello.s -o write-hello.oアセンブリ言語について詳しくは、2年生の「機械語序論」で学ぶ。 システムコールについて詳しくは、3年生の「システムプログラム」で学ぶ。% ld -o write-hello write-hello.o
% ls -l write-hello*
-rwxr-xr-x 1 yas lab 776 Feb 5 23:17 write-hello -rw-r--r-- 1 yas lab 588 Feb 5 23:17 write-hello.o -rw-r--r-- 1 yas lab 330 Feb 5 23:17 write-hello.s % ./write-hello
hello %
![]()
アセンブリ言語(機械語)は、機械にはわかりやすいが 人間にはわかりにくい。
注意:「ライブラリ」にはいくつかの意味がある。オペレーティング・システ ムの文脈では、システムコールとライブラリを区別する。
図? ソース・プログラムらプロセスまで
% cat -n today.c1 #define TODAY "Monday" 2 main() 3 { 4 printf("Today is %s.\n",TODAY ); 5 } % cc today.c
% ./a.out
Today is Monday. %
![]()
% cc -v today.cReading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1) /usr/lib/gcc-lib/i386-redhat-linux/2.96/cpp0 -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=96 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__NO_INLINE__ -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__tune_i386__ today.c /tmp/ccjgHuug.i GNU CPP version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1) (cpplib) (i386 Linux/ELF) ignoring nonexistent directory "/usr/i386-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/lib/gcc-lib/i386-redhat-linux/2.96/include /usr/include End of search list. /usr/lib/gcc-lib/i386-redhat-linux/2.96/cc1 /tmp/ccjgHuug.i -quiet -dumpbase today.c -version -o /tmp/ccmZ7Ykn.s GNU C version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1) (i386-redhat-linux) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1). as -V -Qy -o /tmp/cc3OlW9w.o /tmp/ccmZ7Ykn.s GNU assembler version 2.10.91 (i386-redhat-linux) using BFD version 2.10.91.0.2 /usr/lib/gcc-lib/i386-redhat-linux/2.96/collect2 -m elf_i386 -dynamic -linker /lib/ld-linux.so.2 /usr/lib/gcc-lib/i386-redhat-linux/2.96/../ ../../crt1.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/../../../crti.o / usr/lib/gcc-lib/i386-redhat-linux/2.96/crtbegin.o -L/usr/lib/gcc-lib/i 386-redhat-linux/2.96 -L/usr/lib/gcc-lib/i386-redhat-linux/2.96/../../ .. /tmp/cc3OlW9w.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-redhat-linux/ 2.96/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/../../../crtn.o %
![]()
図? ccコマンドの背後で動いているプログラム
% cat today.cC言語のプリプロセッサは、C言語そのものではなく、マクロプロセッサ。#define TODAY "Monday" main() { printf("Today is %s.\n",TODAY ); } % cc -E today.c > today.i
% cat today.i
% 2 "today.c"
main() { printf("Today is %s.\n","Monday" ); } %
![]()
% cpp today.c% 2 "today.c"
main() { printf("Today is %s.\n","Monday" ); } %
![]()
% cppCプリプロセッサの機能#define apple orange
apple computer
^D % 2 ""
orange computer %
![]()
% 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
%
![]()
% cat today.c#define TODAY "Monday" main() { printf("Today is %s.\n",TODAY ); } % cc -S today.c
% cat today.s
.file "today.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "Monday" .LC1: .string "Today is %s.\n" .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $8, %esp subl $8, %esp pushl $.LC0 pushl $.LC1 call printf addl $16, %esp leave ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1)" %
![]()
% cc -c today.c% ls -l today.o
-rw-r--r-- 1 yas lab 940 Feb 6 01:09 today.o % nm today.o
00000000 t gcc2_compiled. 00000000 T main U printf %
![]()
% cc -v today.o -o a.out様々なライブラリら実行時ルーチンが参照されている。Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1) /usr/lib/gcc-lib/i386-redhat-linux/2.96/collect2 -m elf_i386 -dynamic -linker /lib/ld-linux.so.2 -o a.out /usr/lib/gcc-lib/i386-redhat-linux /2.96/../../../crt1.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/../../.. /crti.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/crtbegin.o -L/usr/lib/ gcc-lib/i386-redhat-linux/2.96 -L/usr/lib/gcc-lib/i386-redhat-linux/2. 96/../../.. today.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-redhat-linux /2.96/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/2.96/../../../crtn.o %
![]()
逆アセンブラは、機械語をアセンブリ言語に戻す。 gdb (GNU Debugger) には、逆アセンブルの機能がある。
% cc -c today.c% ls -l today.o
-rw-r--r-- 1 yas lab 940 Feb 6 01:09 today.o %
% gdb today.o
GNU gdb Red Hat Linux (5.1-0.71) Copyright 2001 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 "i386-redhat-linux"... (no debugging symbols found)... (gdb) x/8x main
0x0
: 0x83e58955 0xec8308ec 0x00006808 0x07680000 0x10 : 0xe8000000 0xfffffffc 0xc910c483 0x00768dc3 (gdb) x/10i main 0x0
: push %ebp 0x1 : mov %esp,%ebp 0x3 : sub $0x8,%esp 0x6 : sub $0x8,%esp 0x9 : push $0x0 0xe : push $0x7 0x13 : call 0x14 0x18 : add $0x10,%esp 0x1b : leave 0x1c : ret (gdb) ![]()
以下は、Lisp の一種、Scheme での実行例。
% schemeWelcome to MzScheme version 201, Copyright (c) 1995-2002 PLT > (+ 1 2 3)
6 > (define (print-hello ) (print "hello"))
> (print-hello)
"hello">
プログラミング言語の2種類の動作方法の違い
図? javac コマンドと java コマンド
% cat PrintHello.javajavaコマンドは、「Javaバイトコード」を解釈実行する変りに、機械語にコン パイルして実行することもある。このコンパイラは、Just in time (JIT) コ ンパイラと呼ばれる。class PrintHello { public static void main(String args[]) { System.out.println("hello"); } } % javac PrintHello.java
% ls PrintHello.*
PrintHello.class PrintHello.java % java PrintHello
hello %
![]()
2種類の仮想計算機
Java仮想計算機を使うと、さまざまな種類ハードウェア(CPU)やオペレーティ
ング・システムで共通にバイトコードが使えるようになる。
図? 共通のバイトコードが使える
インタプリタ(仮想計算機)の大部分は、C言語で記述されている。 インタプリタ自身は、それぞのハードウェアの機械語にコンパイルされている。
% ls PrintHello.classPrintHello.class % javap -c PrintHello
Compiled from PrintHello.java class PrintHello extends java.lang.Object { PrintHello(); public static void main(java.lang.String[]); } Method PrintHello() 0 aload_0 1 invokespecial #1
4 return Method void main(java.lang.String[]) 0 getstatic #2 3 ldc #3 5 invokevirtual #4 8 return % ![]()