a21_txt02_2a
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.04.15)
** (1) HL-12a
-今回のテーマは、本当にちゃんとコード生成できているのかの...
(前略)
int phrCmpPutIcX86(int pid, String phr, int pc, int *pi,...
int codedump; [この行追加]
////////////////////////////////////////////////////////...
int compile(String s)
{
(中略)
jp = 0;
putIcX86("60; 83_ec_7c;", 0, 0, 0, 0); // PUSHAD(); ...
+ dump0 = icq;
for (i = 0; i < 10; i++) {
tmp_flag[i] = 0;
}
tmpLabelNo = 0;
bd = lbd = 0;
for (pc = 0; pc < pc1; ) { // コンパイル開始.
(中略)
+ } else if (phrCmp(35, "code", pc)) {
+ for (pc++; tc[pc] != TcSemi; pc++) {
+ if (tc[pc] == TcComma) continue;
+ *icq = var[tc[pc]];
+ icq++;
+ }
+ ppc1 = pc + 1;
+ } else if (phrCmp(36, "codedump !!*0;", pc)) {
+ codedump = var[tc[wpc[0]]];
} else if (phrCmp( 8, "!!***0;", pc)) { // これ...
e0 = expr(0);
} else
goto err;
tmpFree(e0);
tmpFree(e2);
if (e0 < 0 || e2 < 0) goto err;
pc = ppc1;
}
if (bd > 0) {
printf("block nesting error (bd=%d, lbd=%d, pc=%...
return -1;
}
+ dump1 = icq;
putIcX86("83_c4_7c; 61; c3;", 0, 0, 0, 0); // ADD(ES...
icq1 = icq;
(中略)
}
int run(String s)
{
if (compile(s) < 0)
return 1;
+ if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
+ } else {
+ int i, i1 = dump1 - dump0;
+ for (i = 0; i < i1; i++) {
+ printf("%02x ", dump0[i]);
+ }
+ printf("\n(len=%d)\n", i1);
+ }
return 0;
}
(後略)
-プログラムは766行になりました。
-今回コマンドを2つ作ったのですが、1つめのcodedumpは「生成...
>codedump 1
(len=0)
>a=1
8b 05 d0 f9 41 00 89 05 d8 fa 41 00
(len=12)
-codedump 1 のときは、機械語が表示されるだけで実行はされ...
-codedump 0 を実行すれば普通の実行モードに戻ります。
-2つめのcode命令は、かなり強烈な命令です。16進数を並べる...
-私はこの命令を使って、「こういう機械語にしたら何秒で実行...
-どちらも具体的な例を、(2)や(3)で説明します。
** (2) codedumpの結果を見てみる
>codedump 1
(len=0)
>run hl3.txt
8b 05 cc f9 41 00 89 05 d8 fa 41 00 8b 05 d8 fa
41 00 40 89 05 d8 fa 41 00 3b 05 e0 fa 41 00 0f
8c e7 ff ff ff e8 99 1c d9 ff
(len=42)
-さてこの結果はあっているでしょうか?このままだとみにくい...
8b 05 cc f9 41 00; 89 05 d8 fa 41 00; // EAX = [0]; ...
8b 05 d8 fa 41 00; 40; 89 05 d8 fa 41 00; // EAX = [i]; ...
3b 05 e0 fa 41 00; 0f 8c e7 ff ff ff; // CMP(EAX,[10...
e8 99 1c d9 ff; // CALL sub_ti...
-おお、ちゃんとできている!・・・とりあえずJITコンパイラ...
** (3) code命令を使ってみる
-gcc-O3が生成した10億回ループのコードを実行してみます。
>code 0xb8 0xff 0xc9 0x9a 0x3b 0x48 0x79 0xfd; time;
-おお、やっぱり速い。さすがです。これと同じコードを作れる...
// >code 0xbb 0x00 0x36 0x65 0xc4 0x43 0x0f 0x88 0xf9 0xf...
>code 0x31 0xdb 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 ...
-よし、同じ速さが出ています。コードの長さは負けていますが...
--なお、上記のたくさんの0x90(NOP)は分岐先アドレスのアライ...
-私は最適化の方法を検討するとき、この例のようにcode命令を...
-また「CPUにはこういう命令があるらしい」みたいなときに試...
--「アセンブラのソースコードを書いてアセンブルして実行す...
** 次回に続く
-次回: [[a21_txt02_3]]
*こめんと欄
#comment
終了行:
* 「10日くらいでできる!プログラミング言語自作入門」の続...
-(by [[K]], 2021.04.15)
** (1) HL-12a
-今回のテーマは、本当にちゃんとコード生成できているのかの...
(前略)
int phrCmpPutIcX86(int pid, String phr, int pc, int *pi,...
int codedump; [この行追加]
////////////////////////////////////////////////////////...
int compile(String s)
{
(中略)
jp = 0;
putIcX86("60; 83_ec_7c;", 0, 0, 0, 0); // PUSHAD(); ...
+ dump0 = icq;
for (i = 0; i < 10; i++) {
tmp_flag[i] = 0;
}
tmpLabelNo = 0;
bd = lbd = 0;
for (pc = 0; pc < pc1; ) { // コンパイル開始.
(中略)
+ } else if (phrCmp(35, "code", pc)) {
+ for (pc++; tc[pc] != TcSemi; pc++) {
+ if (tc[pc] == TcComma) continue;
+ *icq = var[tc[pc]];
+ icq++;
+ }
+ ppc1 = pc + 1;
+ } else if (phrCmp(36, "codedump !!*0;", pc)) {
+ codedump = var[tc[wpc[0]]];
} else if (phrCmp( 8, "!!***0;", pc)) { // これ...
e0 = expr(0);
} else
goto err;
tmpFree(e0);
tmpFree(e2);
if (e0 < 0 || e2 < 0) goto err;
pc = ppc1;
}
if (bd > 0) {
printf("block nesting error (bd=%d, lbd=%d, pc=%...
return -1;
}
+ dump1 = icq;
putIcX86("83_c4_7c; 61; c3;", 0, 0, 0, 0); // ADD(ES...
icq1 = icq;
(中略)
}
int run(String s)
{
if (compile(s) < 0)
return 1;
+ if (codedump == 0) {
void (*func)() = (void (*)()) ic;
t0 = clock();
func();
+ } else {
+ int i, i1 = dump1 - dump0;
+ for (i = 0; i < i1; i++) {
+ printf("%02x ", dump0[i]);
+ }
+ printf("\n(len=%d)\n", i1);
+ }
return 0;
}
(後略)
-プログラムは766行になりました。
-今回コマンドを2つ作ったのですが、1つめのcodedumpは「生成...
>codedump 1
(len=0)
>a=1
8b 05 d0 f9 41 00 89 05 d8 fa 41 00
(len=12)
-codedump 1 のときは、機械語が表示されるだけで実行はされ...
-codedump 0 を実行すれば普通の実行モードに戻ります。
-2つめのcode命令は、かなり強烈な命令です。16進数を並べる...
-私はこの命令を使って、「こういう機械語にしたら何秒で実行...
-どちらも具体的な例を、(2)や(3)で説明します。
** (2) codedumpの結果を見てみる
>codedump 1
(len=0)
>run hl3.txt
8b 05 cc f9 41 00 89 05 d8 fa 41 00 8b 05 d8 fa
41 00 40 89 05 d8 fa 41 00 3b 05 e0 fa 41 00 0f
8c e7 ff ff ff e8 99 1c d9 ff
(len=42)
-さてこの結果はあっているでしょうか?このままだとみにくい...
8b 05 cc f9 41 00; 89 05 d8 fa 41 00; // EAX = [0]; ...
8b 05 d8 fa 41 00; 40; 89 05 d8 fa 41 00; // EAX = [i]; ...
3b 05 e0 fa 41 00; 0f 8c e7 ff ff ff; // CMP(EAX,[10...
e8 99 1c d9 ff; // CALL sub_ti...
-おお、ちゃんとできている!・・・とりあえずJITコンパイラ...
** (3) code命令を使ってみる
-gcc-O3が生成した10億回ループのコードを実行してみます。
>code 0xb8 0xff 0xc9 0x9a 0x3b 0x48 0x79 0xfd; time;
-おお、やっぱり速い。さすがです。これと同じコードを作れる...
// >code 0xbb 0x00 0x36 0x65 0xc4 0x43 0x0f 0x88 0xf9 0xf...
>code 0x31 0xdb 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90 ...
-よし、同じ速さが出ています。コードの長さは負けていますが...
--なお、上記のたくさんの0x90(NOP)は分岐先アドレスのアライ...
-私は最適化の方法を検討するとき、この例のようにcode命令を...
-また「CPUにはこういう命令があるらしい」みたいなときに試...
--「アセンブラのソースコードを書いてアセンブルして実行す...
** 次回に続く
-次回: [[a21_txt02_3]]
*こめんと欄
#comment
ページ名: