ぼんさい塾

ぼんさいノートと補遺に関する素材や注釈です.ミスが多いので初稿から1週間を経た重要な修正のみ最終更新日を残しています.

L8プログラミング (7)

2013-07-28 23:18:13 | 暮らし
IT.pdf
IT-s.pdf
IT-e.pdf

記事一覧
 
          ジャンプテーブルによる分岐
       (2013-08-31:ジャンプ命令を訂正)

IT-e.pdf に switch 文に関する説明を追加しました.アセンブラを使ったことのない人には if-else 文も switch 文も実態は似たようなものだと思っているかもしれませんが,少なくとも本来の用法(※)ではコンパイルの仕方が全然違います.
※ 「本来の用法」は単なる推測ですが,break 文がなければフォールスルーが起こると言うのは [#18%35] の「RET」を「NOP」で置換したときの現象を想像させます.

メモ:次の資料を引用しています
[1] カーニハン&リッチー,プログラミング言語C 第2版 ANSI規格準拠
  http://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9EC-%E7%AC%AC2%E7%89%88-ANSI%E8%A6%8F%E6%A0%BC%E6%BA%96%E6%8B%A0-B-W-%E3%82%AB%E3%83%BC%E3%83%8B%E3%83%8F%E3%83%B3/dp/4320026926
[2] switch文 - Wikipedia
  http://ja.wikipedia.org/wiki/Switch%E6%96%87
[3] case文(switch文)の実装
  http://www.tokumaru.org/memo/memo002.htm
  初期のCabezonは、以下の三種類のコードの中から、メモリ使用量が最も少ないコードを・・・
[4] Chapter 1 : C/C++に於けるジャンプテーブルの実装に関する考察 (2001 ...
  http://gigo.retrogames.com/t_lab/chapter1.html
  アセンブラのように ・・・jmp dword ptr [cur_tbl+op_code*4] のような実装は出来ず、(vs [3])
-----
(1) [1]の A9.4 選択文に「この制御式は整数格上げ(A6.1節)を受け,case 定数は格上げされた型へ変換される」と書かれているだけですが,case 定数の取りうる範囲が狭く,ジャンプテーブルを使って即座にジャンプするのが本来の用法です.だだし,switch 文はソースを読み易いので多くの言語で使われ,C# のように文字列まで許すこともあるので実装の仕方が多様化しているようです[2][3].
(2) 初期のマイクロコンピュータのアセンブリ言語で書かれたモニタプログラムではコンソールから入力するコマンドを D(dump),G(go)のように1文字で表わし,後に引数を付けていました --- A から Z に対応する 26行 のジャンプテーブルを使用.
(3) IT-e.pdf [#18%35] のジャンプテーブルはCの関数へのポインタの配列に対応していますが,関数へのポインタの使い方の説明は省略します --- 興味のある人は[1] 5.11 等を見てください. 


L8プログラミング (6)

2013-07-27 18:35:05 | 暮らし
IT.pdf
IT-s.pdf
IT-e.pdf

記事一覧

 
                      〔P8〕のLONG 型
               (通常の仕様と異なります)

IT-e.pdf に LONG 型の実装例を示しました.〔P8〕には桁上げのフラグが無いので取りうる値の絶対値は 16383 以下に制限しています ---〔Z〕しかなくても多倍長の数値を扱えるというデモです(特殊仕様なので真似をしないでください).

メモ:(1) 〔P8〕の「ADD」「SUB」は mod 256 で考えていて 100 と -156 を同一視しますが,LONG 型に対しては各語の値は計算途中でも区間 [-128, 128) で考えます.
(2) n = Σ0≦k≦m  nk・128k (-64≦ k <64 )の多倍長整数も同様 --- 各語に入る値は正負入り乱れますが気にしなくてよいと思います.
(3) 命令語の16進表示に合わせて,LONG 型のデータの16進表示でも上位バイトが左側にくるように実装しました --- ビッグエンディアン,リトルエンディアンの説明は
  http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3%E3%83%87%E3%82%A3%E3%82%A2%E3%83%B3
を参照してください.


L8プログラミング (5)

2013-07-25 18:34:48 | 暮らし
IT.pdf
IT-s.pdf
IT-e.pdf

記事一覧

                       引数と自動変数をもつ関数

IT-e.pdf に高級言語のコンパイルに関する説明を追加しました.非常に簡単な例ですが,引数や自動変数(静的でない局所変数)をスタック上に置くことの実態が分かると思います.

メモ:以下のメモを読む前に [%33B] に示した資料
[1] コールスタック - Wikipedia
  http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%AB%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF
[2] 呼出規約 - Wikipedia
  http://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA%E8%A6%8F%E7%B4%84
[3] HACK#9 デバッグに必要なスタックの基礎知識(685KB)
  http://www.oreilly.co.jp/editors/debug_hacks_09.pdf
を見てください.また次の資料も以下で引用します.
------------------
[4] X86アセンブラ/x86アーキテクチャ - Wikibooks
  http://ja.wikibooks.org/wiki/X86%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9/x86%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3
[5] Intel 8086 - ウィキペディア - Wikipedia
  http://ja.wikipedia.org/wiki/Intel_8086
  英語版:http://en.wikipedia.org/wiki/Intel_8086 (サンプルプログラムあり)
------------------
(1) [1] で説明されているフレームポインタの具体例が [3] のサンプルプログラムの ebp(bp を32ビット化したレジスタ)です.
(2) i8086 の時から [4] の英語版に書かれている"mov ax,[bx + di + 10]" のようなアドレス指定をできましたが,[5] では紹介されていません.レジスタを2個使うとスタック上にある構造体配列のメンバも分かりやすくなります.
(3) int sum(int i, int k){return i+k;} は例えば
    SUM   LD    R0, 1, R3
          ADD   R0, 2, R3
          RET
前記の [3] の例でも eax に戻り値を設定していますが,スタック上に置くように定めてもよい.
(4) [%32] の「LDA   R3, -2, R3」の処理を RET 側で行うには,例えば
    RET   MACRO  X
          LDA    R3, X, R3
          RET
          ENDM 
これを用いると RET 側の「LDA   R3, 1, R3」も X に統合できます.


L8プログラミング (4)

2013-07-23 16:57:48 | 暮らし
IT.pdf
IT-s.pdf
IT-e.pdf

記事一覧

           L8のマクロの例

IT-e.pdf にマクロに関する説明を追加しました.

メモ:(1) とりあえず CASLⅡの PUSH, POP, CALL, RET に対応するマクロの定義例を示しました.また NOR を用いれば NOT, AND, OR のマクロも作れます.
(2) 名前呼びの引数もつ関数をアセンブルするときの処理について,かつて講義した基本情報技術者試験,平成12年秋,問3

         

が記憶に残っていますが,古すぎて
  http://www.jitec.ipa.go.jp/1_04hanni_sukiru/_index_hanni_skill.html#mondai_kaito
  http://情報処理試験.jp/index.html
  http://www.fe-siken.com/
等の“過去問”からは検索できません.類似の新しい問題があると思いますが「情報技術者試験 H12 秋 問3」で検索して得られた
  http://kihon.3rin.net/%E7%AC%AC%E4%BA%8C%E7%A8%AE%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%EF%BC%9A%E5%B9%B3%E6%88%9012%E5%B9%B4%E5%BA%A6%E7%A7%8B%E6%9C%9F/%E5%95%8F3%EF%BC%9A%E5%B9%B3%E6%88%9012%E5%B9%B4%E7%A7%8B%E6%9C%9F%E3%80%80%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93%E3%80%80%E9%81%8E%E5%8E%BB%E5%95%8F%E9%A1%8C_143
を紹介します.


L8プログラミング (3)

2013-07-21 08:38:59 | 暮らし
IT.pdf
IT-s.pdf
IT-e.pdf

記事一覧
 
フローチャート

IT-e.pdf に 文字列の扱いに関する説明を追加しました.

メモ:(1) サンプルプログラムの処理内容は上図のようなフローチャートで表わすと分かり易くなりますが IT-e.pdf では動作原理の理解という点に集中して手抜きします.
(2) 解答例は C プログラムの
    char c, s[] = "HELLO."; int found = 1, i = 0;
    while(1){
        c = s[i]; i++;
        if(c == 'E') break;
        if(c != '.'){found = 0; break;}
    }
にほぼ対応しています.これに対して
          LDA   R1, 0
    LOOP  LD    R0, STR, R1
          LDA   R1, 1, R1

          LDA   R1, STR
    LOOP  LD    R0, 0, R1
          LDA   R1, 1, R1
に変更したプログラムは C の
    char s[] = "HELLO.", *p = s; int found = 1;
    while(1){
        c = *p; p++;
        if(c == 'E') break;
        if(c != '.'){found = 0; break;}
    }
にほぼ対応します.
(3)「LD    R2, STR, R1」「LDA   R0, -'E', R2」ではフラグは変わりません.