page0100
の編集
http://osecpu.osask.jp/wiki/?page0100
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
BracketName
FormattingRules
FrontPage
Fulyn
Fulyn-v2
Fulyn_Samples
Help
InterWiki
InterWikiName
InterWikiSandBox
K
KOR_PIT8254
KWVM.NET
Liva
MANA
MenuBar
OSECPU_FPGA
PG_MANA
PHP
PukiWiki
PukiWiki/1.4
PukiWiki/1.4/Manual
PukiWiki/1.4/Manual/Plugin
PukiWiki/1.4/Manual/Plugin/A-D
PukiWiki/1.4/Manual/Plugin/E-G
PukiWiki/1.4/Manual/Plugin/H-K
PukiWiki/1.4/Manual/Plugin/L-N
PukiWiki/1.4/Manual/Plugin/O-R
PukiWiki/1.4/Manual/Plugin/S-U
PukiWiki/1.4/Manual/Plugin/V-Z
RecentDeleted
SandBox
WikiEngines
WikiName
WikiWikiWeb
YukiWiki
hikalium
hikarupsp
hikarupsp_ELCHNOS
hikarupsp_ELCHNOS_IDE
hikarupsp_FrontEndCode
hikarupsp_WebCPU-VM
hikarupsp_WebCPU-VM_internal
hikarupsp_study_hh4
impressions
impressions0000
jpag0000
jpag0001
jpag0002
jpag0003
jpag0004
jpag0005
lambdalice
mandel59
members
memo0000
memo0001
memo0002
memo0003
memo0004
memo0005
memo0006
memo0007
memo0008
memo0009
memo0010
osask
osecpu4android
page0000
page0001
page0002
page0003
page0004
page0005
page0006
page0007
page0008
page0009
page0010
page0011
page0012
page0013
page0014
page0015
page0016
page0017
page0018
page0019
page0020
page0021
page0022
page0023
page0024
page0025
page0026
page0027
page0028
page0029
page0030
page0031
page0032
page0033
page0034
page0035
page0036
page0037
page0038
page0039
page0040
page0041
page0042
page0043
page0044
page0045
page0046
page0047
page0048
page0049
page0050
page0051
page0052
page0053
page0054
page0055
page0056
page0057
page0058
page0059
page0060
page0061
page0062
page0063
page0064
page0065
page0066
page0067
page0068
page0069
page0070
page0071
page0072
page0073
page0074
page0075
page0076
page0077
page0078
page0079
page0080
page0081
page0082
page0083
page0084
page0085
page0086
page0087
page0088
page0089
page0090
page0091
page0092
page0093
page0094
page0095
page0096
page0097
page0098
page0099
page0100
page0101
page0102
page0103
page0104
page0105
page0106
page0107
page0108
page0109
pagenames
populars
seccamp2013
seccamp2014
seccamp2017
ttwilb
ttwilb-asmi
yao
* フロントエンドコードを見てみよう -(by [[K]], 2014.07.16) ** (0) -osecpu121dより、osectolsにdumpfrというツールが追加されました。それの紹介みたいなものです。 -ちなみに、ここで示されているバイトコードはosecpu121dのもので、将来のバージョンでは改善されている可能性があります。 -このページの内容は古いです。&color(#f00){最新版};はこちらです。→[[page0101]] ** (1) -app0100_.oseを最初の例にしようと思います。 -これはカラーグラデーションのアプリで、昨年のrev1のころはこれが17バイトで書けることですごいと言われましたが、現在のrev2では&color(#f00){''13バイト''};になっています。 ~ http://osecpu.osask.jp/download/app0006a.png -ソースコードは以下の通りです。 #include "osecpu_ask.h" Int32s c:R00, x:R01, y:R02; api_openWin(256, 256); // c = 0; for (x = 0; x != 256; x++) { for (y = 0; y != 256; y++) { api_drawPoint(MODE_COL24, c, x, y); c += 0x100; } } --少し補足すると、c = 0;がコメントアウトされているのは、OSECPU-VMでは整数レジスタの初期値が0であることが保障されているので、これを省略してバイナリサイズを節約しているのです。 -このアプリのフロントエンドコードをバイナリエディタ等で確認すると次のようになっています。 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c 0000: 05 e2 59 0b b0 61 bb 62 bb 45 23 00 bb --この通り間違いなく13バイトなのですが、しかしこれでは少し読みにくいです。 -ということで、これを命令ごとに切って表示させてみます。 prompt>osectols tool:dumpfr in:app0100_.ose 0000: 05e2 OSECPU-VMアプリの2バイトのシグネチャ 0004: 5_90_bb_0 api_openWin(256, 256); 000a: 6_1_bb for (R01 = 0; R01 != 256; R01++) { ... 000e: 6_2_bb for (R02 = 0; R02 != 256; R02++) { ... 0012: 4_5_2_3 api_drawPoint(MODE_COL24, R00, R01, R02); 0016: 0_0_bb R00 += 0x100; --上記のダンプリストと比べると、命令の区切りやパラメータが分かりやすくなっています。 --4回ほど出てくるbbが定数の256を意味しています。rev1→rev2では定数256を表現するために必要なバイトコードが1.5バイトから1.0バイトに変更されたので、グラデーションアプリはそれだけで2バイトも改善されました(4バイトの改善のうちの半分はこの効果によるものです)。 --命令番号6がfor文を表していることも観察できると思います。 ** (2) -app0115_.oseを次の例にしようと思います。これは2014年度のキャンプ生がOSECPU-VMの勉強用に作ったものです。 -バイナリサイズはわずか&color(#f00){''19バイト''};ですが、とてもきれいな模様が出ます。 ~ http://osecpu.osask.jp/download/app0115.png -ソースコードは以下の通りです。 #include "osecpu_ask.h" Int32s x:R01, y:R02, c:R00; api_openWin(256, 256); for (y = 0; y != 256; y++) { for (x = 0; x != 256; x++) { c = x ^ y; c *= 0x10101; api_drawPoint(MODE_COL24, c, x, y); } } -フロントエンドバイトコードは次のようになります。 prompt>osectols tool:dumpfr in:app0115_.ose 0000: 05e2 0004: 5_90_bb_0 api_openWin(256, 256); 000a: 6_2_bb for (R01 = 0; R01 != 256; R01++) { ... 000e: 6_1_bb for (R02 = 0; R02 != 256; R02++) { ... 0012: 4_91_2_0_0 R00 = R01 ^ R02; 0018: 96_2_7510101 R00 *= 0x10101; 0022: 4_5_2_3 api_drawPoint(MODE_COL24, R00, R01, R02); --ここで演算命令を少し詳しく見てみようと思います。 --OSECPU-VMでは、R00 = R01 ^ R02;が3バイトで記述できています。これはすごいのでしょうか。すごくないのでしょうか。 --同じことをx86でやるとなると、EAX = ECX; EAX ^= EDX;になると思います。これは89_c8 31_d0とかになって、4バイトを要します。 --同様にR00 *= 0x10101;についても比較してみます。OSECPU-VMは5バイトです。それに対してx86では69_c0_00010101とかになって、6バイトを要します。 ** (3) -app0103_.oseを次の例にしようと思います。毎度おなじみのbballアプリです。 -バイナリサイズはわずか&color(#f00){''68バイト''};ですが、とてもきれいな模様が出ます。 ~ http://osecpu.osask.jp/download/bball.png -ちなみにバイナリサイズの比較です。 「はりぼてOS」 350バイト(改良の余地あり、参考記録) 第一世代OSASK 186バイト TownsOS 185バイト MSX-DOS/MSX2 140バイト Human68k+IOCS 116バイト MS-DOS/NEC PC-9801 114バイト (OSECPU-VM以外での世界最小記録) OSECPU-VM (rev1) 71バイト OSECPU-VM (rev2) 68バイト -ソースコードは以下の通りです。 --(準備中) -フロントエンドバイトコードは次のようになります。 prompt>osectols tool:dumpfr in:app0103_.ose 0000: 05e2 0004: ae_3_a0_c464bb3da41d81095a053511172c07510777179c35b75ac381bfa4abbb8bc464 0049: 6_5_8f for (R05 = 0; R05 != 15; R05++) { 004d: 88_1_0_1 R01 = *P01++; 0052: 88_2_0_2 R02 = *P01++; 0057: 4_3_0_2 P02 = &data[0]; 005b: 4_6_6_d8c_88 for (R06 = -8; R06 != 8; R06++) { 0063: 4_95_5_0_0 R00 = R05 - R06; 0069: 88_2_0_3 R03 = *P01++; 006e: 88_2_0_4 R04 = *P01++; 0073: a5_4_0 if (R00 <= 0) { 0077: 8d_95_2_1 R00 = 1- R00; 007d: 1 } 007e: a5_2_87 if (R00 <= 7) { 0083: 4_5_3_4 api_drawLine(MODE_OR, R00, R01, R02, R03, R04); } 0087: 0 -aeで始まるデータ記述命令を1命令と数えても、14命令しかありません(末尾の0は0.5バイト余ったので入れているだけです)。 ** (4) -app0116_.oseを次の例にしようと思います。これも2014年度のキャンプ生がOSECPU-VMで関数呼び出しの勉強用に作ったものです。 -バイナリサイズはわずか&color(#f00){''85バイト''};ですが、Cカーブが再帰深さを変えつつ表示されます。 ~ http://osecpu.osask.jp/download/app0117b.gif ~ (gifアニメです) -ソースコードは以下の通りです。 #include "osecpu_ask.h" #define L_func LOCAL(0) LOCALLABELS(1); #define func(x1, y1, x2, y2, c) R00=c; R01=x1; R02=y1; R03=x2; R04=y2; CALL(L_func); // main do { Int32s ax:R01, ay:R02, bx:R03, by:R04, count:R00; for (count = 0; count != 13; count++) { api_openWin(768, 768); func(256, 256, 512, 256, count); func(512, ay, bx, 512, count); func(ax, 512, 256, by, count); func(256, ay, bx, 256, count); api_sleep(0, 1024); } } api_end(); beginFunc(L_func); do { Int32s ax:R01, ay:R02, bx:R03, by:R04, count:R00; Int32s ux:R05, uy:R06, tx:R07, ty:R08; count--; if (count >= 0) { // ux = (by - ay + ax + bx) / 2; // uy = (ax - bx + ay + by) / 2; tx = ax + by; ty = bx - ay; ux = tx + ty; uy = tx - ty; ux /= 2; uy /= 2; tx = bx; ty = by; func(ax, ay, ux, uy, count); func(ux, uy, tx, ty, count); } else { // count = -1; api_drawLine(MODE_COL3, count, ax, ay, bx, by); } } endFunc(); --ソースコードは43行あります。これが85バイトになるということは、1行あたり2バイト程度になっているということです。・・・コメントや空行もあるので、まあそんなものかもしれません。 -フロントエンドバイトコードは次のようになります。 prompt>osectols tool:dumpfr in:app0116_.ose 0000: 05e2 0004: 6_0_8d for (R00 = 0; R00 != 13; R00++) { 0008: 5_90_e300_0 api_openWin(768, 768); 0010: 2_bb_1 R01 = 256; 0014: 2_bb_2 R02 = 256; 0018: 2_d98_3 R03 = 512; 001d: 2_bb_4 R04 = 256; 0021: be_1 CALL(L_func); 0024: 2_d98_1 R01 = 512; 0029: 2_d98_4 R04 = 512; 002e: be_1 CALL(L_func); 0031: 2_d98_2 R02 = 512; 0036: 2_bb_3 R03 = 256; 003a: be_1 CALL(L_func); 003d: 2_bb_1 R01 = 256; 0041: 2_bb_4 R04 = 256; 0045: be_1 CALL(L_func); 0048: 5_89_0_d99 api_sleep(0, 1024); 004f: bc beginFunc(L_func); 0051: 0_6_bf R00--; 0055: a2_2_0 if (count >= 0) { ... 0059: 4_0_4_6_87 (以下省略) 005f: 4_95_6_b5_88 0067: 4_0_5_0_5 006c: 4_95_4_6_6 0072: 99_5_1 0076: 99_3_1 007a: 2_b5_9b 007f: 2_b6_9c 0084: 2_b5_3 0088: 2_b5_4 008c: be_0 008f: 2_b3_1 0093: 2_b3_2 0097: 2_b7_3 009b: 2_b7_4 009f: be_0 00a2: 3_2 00a4: 1 00a5: 4_5_3_0 00a9: 1 -最初の引数の設定のところで、R01 = 256; R02 = 256;という記述がありますが、これはR01 = 256; R02 = R01;のほうが短くなるような気がします。この手の最適化をすべて適用してみると&color(#f00){''80バイト''};になってしまいました! * こめんと欄 #comment
タイムスタンプを変更しない
* フロントエンドコードを見てみよう -(by [[K]], 2014.07.16) ** (0) -osecpu121dより、osectolsにdumpfrというツールが追加されました。それの紹介みたいなものです。 -ちなみに、ここで示されているバイトコードはosecpu121dのもので、将来のバージョンでは改善されている可能性があります。 -このページの内容は古いです。&color(#f00){最新版};はこちらです。→[[page0101]] ** (1) -app0100_.oseを最初の例にしようと思います。 -これはカラーグラデーションのアプリで、昨年のrev1のころはこれが17バイトで書けることですごいと言われましたが、現在のrev2では&color(#f00){''13バイト''};になっています。 ~ http://osecpu.osask.jp/download/app0006a.png -ソースコードは以下の通りです。 #include "osecpu_ask.h" Int32s c:R00, x:R01, y:R02; api_openWin(256, 256); // c = 0; for (x = 0; x != 256; x++) { for (y = 0; y != 256; y++) { api_drawPoint(MODE_COL24, c, x, y); c += 0x100; } } --少し補足すると、c = 0;がコメントアウトされているのは、OSECPU-VMでは整数レジスタの初期値が0であることが保障されているので、これを省略してバイナリサイズを節約しているのです。 -このアプリのフロントエンドコードをバイナリエディタ等で確認すると次のようになっています。 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c 0000: 05 e2 59 0b b0 61 bb 62 bb 45 23 00 bb --この通り間違いなく13バイトなのですが、しかしこれでは少し読みにくいです。 -ということで、これを命令ごとに切って表示させてみます。 prompt>osectols tool:dumpfr in:app0100_.ose 0000: 05e2 OSECPU-VMアプリの2バイトのシグネチャ 0004: 5_90_bb_0 api_openWin(256, 256); 000a: 6_1_bb for (R01 = 0; R01 != 256; R01++) { ... 000e: 6_2_bb for (R02 = 0; R02 != 256; R02++) { ... 0012: 4_5_2_3 api_drawPoint(MODE_COL24, R00, R01, R02); 0016: 0_0_bb R00 += 0x100; --上記のダンプリストと比べると、命令の区切りやパラメータが分かりやすくなっています。 --4回ほど出てくるbbが定数の256を意味しています。rev1→rev2では定数256を表現するために必要なバイトコードが1.5バイトから1.0バイトに変更されたので、グラデーションアプリはそれだけで2バイトも改善されました(4バイトの改善のうちの半分はこの効果によるものです)。 --命令番号6がfor文を表していることも観察できると思います。 ** (2) -app0115_.oseを次の例にしようと思います。これは2014年度のキャンプ生がOSECPU-VMの勉強用に作ったものです。 -バイナリサイズはわずか&color(#f00){''19バイト''};ですが、とてもきれいな模様が出ます。 ~ http://osecpu.osask.jp/download/app0115.png -ソースコードは以下の通りです。 #include "osecpu_ask.h" Int32s x:R01, y:R02, c:R00; api_openWin(256, 256); for (y = 0; y != 256; y++) { for (x = 0; x != 256; x++) { c = x ^ y; c *= 0x10101; api_drawPoint(MODE_COL24, c, x, y); } } -フロントエンドバイトコードは次のようになります。 prompt>osectols tool:dumpfr in:app0115_.ose 0000: 05e2 0004: 5_90_bb_0 api_openWin(256, 256); 000a: 6_2_bb for (R01 = 0; R01 != 256; R01++) { ... 000e: 6_1_bb for (R02 = 0; R02 != 256; R02++) { ... 0012: 4_91_2_0_0 R00 = R01 ^ R02; 0018: 96_2_7510101 R00 *= 0x10101; 0022: 4_5_2_3 api_drawPoint(MODE_COL24, R00, R01, R02); --ここで演算命令を少し詳しく見てみようと思います。 --OSECPU-VMでは、R00 = R01 ^ R02;が3バイトで記述できています。これはすごいのでしょうか。すごくないのでしょうか。 --同じことをx86でやるとなると、EAX = ECX; EAX ^= EDX;になると思います。これは89_c8 31_d0とかになって、4バイトを要します。 --同様にR00 *= 0x10101;についても比較してみます。OSECPU-VMは5バイトです。それに対してx86では69_c0_00010101とかになって、6バイトを要します。 ** (3) -app0103_.oseを次の例にしようと思います。毎度おなじみのbballアプリです。 -バイナリサイズはわずか&color(#f00){''68バイト''};ですが、とてもきれいな模様が出ます。 ~ http://osecpu.osask.jp/download/bball.png -ちなみにバイナリサイズの比較です。 「はりぼてOS」 350バイト(改良の余地あり、参考記録) 第一世代OSASK 186バイト TownsOS 185バイト MSX-DOS/MSX2 140バイト Human68k+IOCS 116バイト MS-DOS/NEC PC-9801 114バイト (OSECPU-VM以外での世界最小記録) OSECPU-VM (rev1) 71バイト OSECPU-VM (rev2) 68バイト -ソースコードは以下の通りです。 --(準備中) -フロントエンドバイトコードは次のようになります。 prompt>osectols tool:dumpfr in:app0103_.ose 0000: 05e2 0004: ae_3_a0_c464bb3da41d81095a053511172c07510777179c35b75ac381bfa4abbb8bc464 0049: 6_5_8f for (R05 = 0; R05 != 15; R05++) { 004d: 88_1_0_1 R01 = *P01++; 0052: 88_2_0_2 R02 = *P01++; 0057: 4_3_0_2 P02 = &data[0]; 005b: 4_6_6_d8c_88 for (R06 = -8; R06 != 8; R06++) { 0063: 4_95_5_0_0 R00 = R05 - R06; 0069: 88_2_0_3 R03 = *P01++; 006e: 88_2_0_4 R04 = *P01++; 0073: a5_4_0 if (R00 <= 0) { 0077: 8d_95_2_1 R00 = 1- R00; 007d: 1 } 007e: a5_2_87 if (R00 <= 7) { 0083: 4_5_3_4 api_drawLine(MODE_OR, R00, R01, R02, R03, R04); } 0087: 0 -aeで始まるデータ記述命令を1命令と数えても、14命令しかありません(末尾の0は0.5バイト余ったので入れているだけです)。 ** (4) -app0116_.oseを次の例にしようと思います。これも2014年度のキャンプ生がOSECPU-VMで関数呼び出しの勉強用に作ったものです。 -バイナリサイズはわずか&color(#f00){''85バイト''};ですが、Cカーブが再帰深さを変えつつ表示されます。 ~ http://osecpu.osask.jp/download/app0117b.gif ~ (gifアニメです) -ソースコードは以下の通りです。 #include "osecpu_ask.h" #define L_func LOCAL(0) LOCALLABELS(1); #define func(x1, y1, x2, y2, c) R00=c; R01=x1; R02=y1; R03=x2; R04=y2; CALL(L_func); // main do { Int32s ax:R01, ay:R02, bx:R03, by:R04, count:R00; for (count = 0; count != 13; count++) { api_openWin(768, 768); func(256, 256, 512, 256, count); func(512, ay, bx, 512, count); func(ax, 512, 256, by, count); func(256, ay, bx, 256, count); api_sleep(0, 1024); } } api_end(); beginFunc(L_func); do { Int32s ax:R01, ay:R02, bx:R03, by:R04, count:R00; Int32s ux:R05, uy:R06, tx:R07, ty:R08; count--; if (count >= 0) { // ux = (by - ay + ax + bx) / 2; // uy = (ax - bx + ay + by) / 2; tx = ax + by; ty = bx - ay; ux = tx + ty; uy = tx - ty; ux /= 2; uy /= 2; tx = bx; ty = by; func(ax, ay, ux, uy, count); func(ux, uy, tx, ty, count); } else { // count = -1; api_drawLine(MODE_COL3, count, ax, ay, bx, by); } } endFunc(); --ソースコードは43行あります。これが85バイトになるということは、1行あたり2バイト程度になっているということです。・・・コメントや空行もあるので、まあそんなものかもしれません。 -フロントエンドバイトコードは次のようになります。 prompt>osectols tool:dumpfr in:app0116_.ose 0000: 05e2 0004: 6_0_8d for (R00 = 0; R00 != 13; R00++) { 0008: 5_90_e300_0 api_openWin(768, 768); 0010: 2_bb_1 R01 = 256; 0014: 2_bb_2 R02 = 256; 0018: 2_d98_3 R03 = 512; 001d: 2_bb_4 R04 = 256; 0021: be_1 CALL(L_func); 0024: 2_d98_1 R01 = 512; 0029: 2_d98_4 R04 = 512; 002e: be_1 CALL(L_func); 0031: 2_d98_2 R02 = 512; 0036: 2_bb_3 R03 = 256; 003a: be_1 CALL(L_func); 003d: 2_bb_1 R01 = 256; 0041: 2_bb_4 R04 = 256; 0045: be_1 CALL(L_func); 0048: 5_89_0_d99 api_sleep(0, 1024); 004f: bc beginFunc(L_func); 0051: 0_6_bf R00--; 0055: a2_2_0 if (count >= 0) { ... 0059: 4_0_4_6_87 (以下省略) 005f: 4_95_6_b5_88 0067: 4_0_5_0_5 006c: 4_95_4_6_6 0072: 99_5_1 0076: 99_3_1 007a: 2_b5_9b 007f: 2_b6_9c 0084: 2_b5_3 0088: 2_b5_4 008c: be_0 008f: 2_b3_1 0093: 2_b3_2 0097: 2_b7_3 009b: 2_b7_4 009f: be_0 00a2: 3_2 00a4: 1 00a5: 4_5_3_0 00a9: 1 -最初の引数の設定のところで、R01 = 256; R02 = 256;という記述がありますが、これはR01 = 256; R02 = R01;のほうが短くなるような気がします。この手の最適化をすべて適用してみると&color(#f00){''80バイト''};になってしまいました! * こめんと欄 #comment
テキスト整形のルールを表示する