バイナリ勉強会 #1


池袋で行われているバイナリ勉強会に初めて、友人と参加させて頂きました。

確か去年も一緒に前期試験が終わった直後に勉強会に参加して、その時は八王子まで出向いた気がします。でもそこでの勉強会は失敗だったんだよな・・・orz

まぁそんな前のことはどうでもいいのですねww

 

まずは大体半年程度を通してのカリキュラムを見せて頂きました。

基礎編ではBrainf*ckのインタプリタの自作から始まり、Cコンパイラの自作、UNIX V6でカーネル入門等々と続きます。

今日はその第一回なので、最初の最初にGtk#(初耳)でBrainf*ckのインタプリタをC#で作ります。

C#初めてで大丈夫かな・・・?とか思ったのですが、指示に従って進めていくとJavaの先代だけあって結構似通ったところがあって理解も進みます。

 

ひとまずこれがほとんど完成したところで昼食をはさんで後半戦に望みます。

お次の指示は、自分の好きな言語で何でもいいのでファイルから読み込んでBrainf*ckのインタプリタを作れとのこと。

ここで最初はC言語で作ろうと思ったのですが、気がついたら何故かC++で作ってましたww

 

今更なのですが、ここでBrainfuckの仕様を説明します。(引用:wikipedia Brainfuck

処理系は次の要素から成る: Brainfuckプログラム、インストラクションポインタ(プログラム中のある文字を指す)、少なくとも30000個の要素を持つバイトの配列(各要素はゼロで初期化される)、データポインタ(前述の配列のどれかの要素を指す。最も左の要素を指すよう初期化される)、入力と出力の2つのバイトストリーム。

Brainfuckプログラムは、以下の8個の実行可能な命令から成る(他の文字は無視され、読み飛ばされる)。

  1. >: ポインタをインクリメントする。ポインタをptrとすると、C言語の「ptr++;」に相当する。
  2. <: ポインタをデクリメントする。C言語の「ptr--;」に相当。
  3. +: ポインタが指す値をインクリメントする。C言語の「(*ptr)++;」に相当。
  4. -: ポインタが指す値をデクリメントする。C言語の「(*ptr)--;」に相当。
  5. .: ポインタが指す値を出力に書き出す。C言語の「putchar(*ptr);」に相当。
  6. ,: 入力から1バイト読み込んで、ポインタが指す先に代入する。C言語の「*ptr=getchar();」に相当。
  7. [: ポインタが指す値が0なら、対応する ] の直後にジャンプする。C言語の「while(*ptr){」に相当。
  8. ]: ポインタが指す値が0でないなら、対応する [ (の直後)にジャンプする。C言語の「}」に相当。

 

・・・開発始める前にちゃんと仕様読めば良かったなぁ。最初[には絶対に一回は入るように作っちゃうから失敗するんだよねww

そんな感じでなんだかんだで完成したのが以下になります。数ヶ月ぶりのちゃんとしたコーディングなので、完全に感覚が鈍っててコードが汚いのは勘弁してください。

#include <iostream>
#include <fstream>
#include <cstdio>

using namespace std;

void func(char[],char[],int*,int*,int*);
int loop[128]={};

int main(void){
 ifstream ifs;
 char c,cmd[2048]={},mem[30000]={};
 int i=0,cps=0,mps=0,lps=0;

 ifs.open("text.bf",ios::in);

 if(!ifs){
  cout << "ファイルが存在しません。" << endl;
  return -1;
 }

 for(i=0;!ifs.eof();i++){
  ifs.get(c);
  cmd[i]=c;
 }
 while(cps<i-1)
  func(cmd,mem,&cps,&mps,&lps);

 ifs.close();
 return 0;
}

void func(char cmd[],char mem[],int *cps,int *mps,int *lps){
 int lev = 0;

 switch(cmd[*cps]){
  case '>':
   ++*mps;
   break;

  case '<':
   --*mps;
   break;

  case '+':
   ++mem[*mps];
   break;

  case '-':
   --mem[*mps];
   break;

  case '[':
   if(mem[*mps]>0){
    ++*lps;
    loop[*lps]=*cps;
   }
   else{
    int lev=1;

    do{
     ++*cps;
     switch(cmd[*cps]){
      case '[':
       ++lev;
       break;

      case ']':
       --lev;
       break;
     }
    }while(lev!=0||cmd[*cps]!=']');

   }
   break;

  case ']':
   if(mem[*mps]>0)
    *cps=loop[*lps];
   else
    --*lps;
   break;

  case '.':
   cout << mem[*mps];
   break;

  case ',':
   mem[*mps]=getchar();
   break;
  }
  ++*cps;
}

ここで初めは","に対して『cin >> mem[*mps]』を使ってたのですが、これだと改行コードが含まれないことが判明したのでgetchar()にしました。
途中break文ごとコメントアウトして何で正常に動かないのだろうとかいうミスをやらかしたりしましたが、結果的に完成したのでよしとしましょう。
ここに完成品を置いておきますね。これはファイル読み込みではなく標準入力にしておきます。

Brainfuckインタプリタ

さて、一通り済んだところで残り時間もわずかになりましたが、次の講座のためにMinGWを準備してbinutilsのインストールまでやっておきます。
・・・ただここで『性能の違い』というものを見せ付けられました。自分のほう(Atom)が先にビルト始めたのに、友人のPC(i5)の方が完全に先に処理を終えるというwwww

 

まぁこんな感じで久しぶりに良い勉強会に当たったようなので、これから常連さんにでもなろうかと思っています。

これからもよろしくお願いします!

OSって奥深いねぇ


昨日から、やっと自作OSの開発に本格的に取り組み始めました!
と言っても、教科書の順を追ってコーディングしてくだけなんですけどねw

川合秀実さんの「OS自作入門」、これ結構分かりやすいですよねぇ~
川合さんは、セキュリティー&プログラミングキャンプ2010のOS自作組で講師をしていらしたようです。
こんなことなら、ネットワークセキュリティ組よか(ry
なんでもありません。元々自分はネットワークの畑でやってこうとしてた者ですから、全くもって問題ないです。
ていうか、もし違う組だったら今知り合ってる人たちとは知り合えなかったのかなぁ・・・?

ま、いいや

今日はそこまで進んではいません。

まあ、まずは皆さんおなじみの「Hello,World」ですよね。
ちょっと小さくて見にくいかもしれません。
まあ、そこらへんは勘弁してください。
これはブートローダだけのとても軽いプログラムです。
因みにアセンブリで書かれています。
次はディスクの読み込みですね。OSたるもの、ちゃんとシステムを読まなきゃブートローダもなにも無いですもんねw
画面には何も表示されませんが、奥でごにょごにょやってるBIOS君やブートローダ君、いつもありがとうございます!

で、次は早速OS本体の製作です。
方針としてはどうやら、はじめのCPU君とメモリ君とのやり取りはアセンブリで行い、その後のOSの機能はC言語で記述していくようです。
でも、OSの中でも直接I/Oやメモリ等々と渡り歩かなきゃいけない時があり 、そのときはまたアセンブリに頼るようです~

早速作ったのは・・・
なんだかしましまですね。
これはVRAMに色の値を書き込んでやっただけなんですが、、、
よくよくみるとこのVRAM結構すごい。
VRAMは全部で64KBあるらしいですが、そのメモリひとつひとつが全ての画素ひとつひとつに割り当てられてるんですってね!
当たり前っちゃ当たり前なんですけど、物を知らない俺にとってはちょっと感動物でした。

続いては四角、四角、刺客もとい四角。
これは単純にx座標方向に連続して同じ値を代入し、それをy座標方向にも同じだけ繰り返す、という作業で正方形ができます。

まあ、そこで本日の〆はこんな感じ。
なんだかWindows95とかってこんな感じでしたっけ?
いきなりやってることが飛んだように見えますがやってることは至って単純。
一旦バックを緑で埋めて、その後下に灰色のタスクバーを生成。後はメニューボタンとかが入りそうなところに影つけてボタンに見せるだけ。
ようは、これボタンじゃないんですよねww

しばらくはこんな感じで本の受け売りが続くかもしれませんが、暖かく見守っていてください。
では~