text0015
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* 川合のプログラミング言語自作のためのテキスト第二版#0006
-(by [[K]], 2019.06.29)
** (13) TJ-03b
-TJ-03aはTL-3dと比較すると圧倒的に高速でしたが、しかしま...
-C言語には「レジスタ変数」という機能があります。しかし最...
-どうですか?面白そうじゃないですか?ということでやってみ...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
typedef unsigned char *String; // こう書くと String は u...
void loadText(int argc, const char **argv, unsigned char...
int isAlphabet(unsigned char c) → TL-2cと同じなので省略
int lexer(String s, String b, String t[]) → TL-2cと同じ...
enum { EAX = 0, ECX = 1, EBX = 3 }; // 定数宣言.
void sub_print(int i) → TJ-03aと同じなので省略
void sub_time() → TJ-03aと同じなので省略
int put32(unsigned char *q, int i) → TJ-03aと同じなので...
int main(int argc, const char **argv)
{
static String def[] = { ";", "=", "+", "-", "print",...
int i, vars = 0, pc, pc1, qc = 0, wqc = 0, wqc2 = 0,...
String t[1000], varName[256]; // トークンと変数名.
unsigned char txt[10000], buf[10000]; // ソースコー...
unsigned char *code = VirtualAlloc(0, 1024 * 1024, M...
void (*func)(); // funcは関数へのポインタ型の変数.
loadText(argc, argv, txt, 10000);
pc1 = lexer(txt, buf, t);
t[pc1] = t[pc1 + 1] = t[pc1 + 2] = t[pc1 + 3] = ""; ...
for (i = 0; def[i] != 0; i++)
varName[i] = def[i];
regvar = vars = i;
code[qc++] = 0x60; // PUSHAD.
code[qc++] = 0x83; // SUB ESP,124. この命令でスタッ...
code[qc++] = 0xec;
code[qc++] = 0x7c;
for (pc = 0; pc < pc1; pc++) {
for (i = 0; i < vars; i++) { // 登録済みの中から...
if (strcmp(t[pc], varName[i]) == 0)
break;
}
if (i == vars) {
varName[i] = t[pc]; // 見つからなかったので...
var[i] = strtol(t[pc], 0, 0); // 初期値を設定.
vars++;
}
varNum[pc] = i;
}
for (pc = 0; pc < pc1; pc++) {
if (varNum[pc + 1] == 1 /* = */) { // 2単語目が"...
if (varNum[pc + 3] == 0 /* ; */) { // 単純代...
if (varNum[pc] == regvar && '0' <= varNa...
code[qc++] = 0xb8 + EBX;
qc += put32(&code[qc], var[varNum[pc...
} else {
if (varNum[pc] == regvar || varNum[p...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0xa3; // MOV [...],EAX
qc += put32(&code[qc], (int) &var[va...
}
} else if (varNum[pc + 3] == 2 /* + */ && va...
if (varNum[pc] == regvar && varNum[pc] =...
code[qc++] = 0x81;
code[qc++] = 0xc0 + EBX;
qc += put32(&code[qc], var[varNum[pc...
} else {
if (varNum[pc] == regvar || varNum[p...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x8b; // MOV ECX,[...]
code[qc++] = ECX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x01;
code[qc++] = 0xc8;
code[qc++] = 0xa3; // MOV [...],EAX
qc += put32(&code[qc], (int) &var[va...
}
} else if (varNum[pc + 3] == 3 /* - */ && va...
if (varNum[pc] == regvar || varNum[pc + ...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x8b; // MOV ECX,[...]
code[qc++] = ECX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x29;
code[qc++] = 0xc8;
code[qc++] = 0xa3; // MOV [...],EAX
qc += put32(&code[qc], (int) &var[va...
} else
goto err;
} else if (varNum[pc] == 5 /* while */ && varNum...
wqc = qc;
if (varNum[pc + 2] == regvar && '0' <= varNa...
code[qc++] = 0x81;
code[qc++] = 0xc0 + 7 * 8 + EBX;
qc += put32(&code[qc], var[varNum[pc + 4...
} else {
if (varNum[pc + 2] == regvar || varNum[p...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[varNum...
code[qc++] = 0x8b; // MOV ECX,[...]
code[qc++] = ECX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[varNum...
code[qc++] = 0x39;
code[qc++] = 0xc8;
}
code[qc++] = 0x0f;
code[qc++] = 0x8d;
qc += put32(&code[qc], 0);
wqc2 = qc;
pc += 7 - 1;
continue;
} else if (varNum[pc] == 10 /* } */) {
code[qc++] = 0xe9;
qc += put32(&code[qc], &code[wqc] - &code[qc...
put32(&code[wqc2 - 4], &code[qc] - &code[wqc...
continue;
} else if (varNum[pc] == 11 /* time */ && varNum...
code[qc++] = 0xe8;
qc += put32(&code[qc], (unsigned char *) sub...
} else if (varNum[pc] == 4 /* print */ && varNum...
if (varNum[pc + 1] == regvar) {
code[qc++] = 0x89;
code[qc++] = 0x04 + EBX * 8;
code[qc++] = 0x24;
} else {
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[varNum...
code[qc++] = 0x89;
code[qc++] = 0x04;
code[qc++] = 0x24;
}
code[qc++] = 0xe8;
qc += put32(&code[qc], (unsigned char *) sub...
} else
goto err;
while (varNum[pc] != 0 /* ; */)
pc++;
}
code[qc++] = 0x83; // ADD ESP,124. 最初に調整したス...
code[qc++] = 0xc4;
code[qc++] = 0x7c;
code[qc++] = 0x61; // POPAD.
code[qc++] = 0xc3; // RET.
func = (void *) code;
func();
exit(0);
err:
printf("syntax error : %s %s %s %s\n", t[pc], t[pc +...
exit(1);
}
-結局どこを改造したのかというと、代入、加算、while、print...
-これにより、処理が以下のように単純化されます。
|処理|普通の変数の場合|レジスタ変数の場合|
|i = 3;|[2命令] MOV(EAX,[....]); MOV([....],EAX);|[1命令]...
|i = i + 5;|[4命令] MOV(EAX,[...]); MOV(ECX,[...]); ADD(E...
-ということで、TJ-03aと比較して4倍くらい速くなります(1億...
-でもgccはさらに速いコードを生成しています。ということで...
** 次回に続く
-次回: [[text0016]]
*こめんと欄
#comment
終了行:
* 川合のプログラミング言語自作のためのテキスト第二版#0006
-(by [[K]], 2019.06.29)
** (13) TJ-03b
-TJ-03aはTL-3dと比較すると圧倒的に高速でしたが、しかしま...
-C言語には「レジスタ変数」という機能があります。しかし最...
-どうですか?面白そうじゃないですか?ということでやってみ...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
typedef unsigned char *String; // こう書くと String は u...
void loadText(int argc, const char **argv, unsigned char...
int isAlphabet(unsigned char c) → TL-2cと同じなので省略
int lexer(String s, String b, String t[]) → TL-2cと同じ...
enum { EAX = 0, ECX = 1, EBX = 3 }; // 定数宣言.
void sub_print(int i) → TJ-03aと同じなので省略
void sub_time() → TJ-03aと同じなので省略
int put32(unsigned char *q, int i) → TJ-03aと同じなので...
int main(int argc, const char **argv)
{
static String def[] = { ";", "=", "+", "-", "print",...
int i, vars = 0, pc, pc1, qc = 0, wqc = 0, wqc2 = 0,...
String t[1000], varName[256]; // トークンと変数名.
unsigned char txt[10000], buf[10000]; // ソースコー...
unsigned char *code = VirtualAlloc(0, 1024 * 1024, M...
void (*func)(); // funcは関数へのポインタ型の変数.
loadText(argc, argv, txt, 10000);
pc1 = lexer(txt, buf, t);
t[pc1] = t[pc1 + 1] = t[pc1 + 2] = t[pc1 + 3] = ""; ...
for (i = 0; def[i] != 0; i++)
varName[i] = def[i];
regvar = vars = i;
code[qc++] = 0x60; // PUSHAD.
code[qc++] = 0x83; // SUB ESP,124. この命令でスタッ...
code[qc++] = 0xec;
code[qc++] = 0x7c;
for (pc = 0; pc < pc1; pc++) {
for (i = 0; i < vars; i++) { // 登録済みの中から...
if (strcmp(t[pc], varName[i]) == 0)
break;
}
if (i == vars) {
varName[i] = t[pc]; // 見つからなかったので...
var[i] = strtol(t[pc], 0, 0); // 初期値を設定.
vars++;
}
varNum[pc] = i;
}
for (pc = 0; pc < pc1; pc++) {
if (varNum[pc + 1] == 1 /* = */) { // 2単語目が"...
if (varNum[pc + 3] == 0 /* ; */) { // 単純代...
if (varNum[pc] == regvar && '0' <= varNa...
code[qc++] = 0xb8 + EBX;
qc += put32(&code[qc], var[varNum[pc...
} else {
if (varNum[pc] == regvar || varNum[p...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0xa3; // MOV [...],EAX
qc += put32(&code[qc], (int) &var[va...
}
} else if (varNum[pc + 3] == 2 /* + */ && va...
if (varNum[pc] == regvar && varNum[pc] =...
code[qc++] = 0x81;
code[qc++] = 0xc0 + EBX;
qc += put32(&code[qc], var[varNum[pc...
} else {
if (varNum[pc] == regvar || varNum[p...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x8b; // MOV ECX,[...]
code[qc++] = ECX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x01;
code[qc++] = 0xc8;
code[qc++] = 0xa3; // MOV [...],EAX
qc += put32(&code[qc], (int) &var[va...
}
} else if (varNum[pc + 3] == 3 /* - */ && va...
if (varNum[pc] == regvar || varNum[pc + ...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x8b; // MOV ECX,[...]
code[qc++] = ECX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[va...
code[qc++] = 0x29;
code[qc++] = 0xc8;
code[qc++] = 0xa3; // MOV [...],EAX
qc += put32(&code[qc], (int) &var[va...
} else
goto err;
} else if (varNum[pc] == 5 /* while */ && varNum...
wqc = qc;
if (varNum[pc + 2] == regvar && '0' <= varNa...
code[qc++] = 0x81;
code[qc++] = 0xc0 + 7 * 8 + EBX;
qc += put32(&code[qc], var[varNum[pc + 4...
} else {
if (varNum[pc + 2] == regvar || varNum[p...
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[varNum...
code[qc++] = 0x8b; // MOV ECX,[...]
code[qc++] = ECX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[varNum...
code[qc++] = 0x39;
code[qc++] = 0xc8;
}
code[qc++] = 0x0f;
code[qc++] = 0x8d;
qc += put32(&code[qc], 0);
wqc2 = qc;
pc += 7 - 1;
continue;
} else if (varNum[pc] == 10 /* } */) {
code[qc++] = 0xe9;
qc += put32(&code[qc], &code[wqc] - &code[qc...
put32(&code[wqc2 - 4], &code[qc] - &code[wqc...
continue;
} else if (varNum[pc] == 11 /* time */ && varNum...
code[qc++] = 0xe8;
qc += put32(&code[qc], (unsigned char *) sub...
} else if (varNum[pc] == 4 /* print */ && varNum...
if (varNum[pc + 1] == regvar) {
code[qc++] = 0x89;
code[qc++] = 0x04 + EBX * 8;
code[qc++] = 0x24;
} else {
code[qc++] = 0x8b; // MOV EAX,[...]
code[qc++] = EAX * 8 + 0x05;
qc += put32(&code[qc], (int) &var[varNum...
code[qc++] = 0x89;
code[qc++] = 0x04;
code[qc++] = 0x24;
}
code[qc++] = 0xe8;
qc += put32(&code[qc], (unsigned char *) sub...
} else
goto err;
while (varNum[pc] != 0 /* ; */)
pc++;
}
code[qc++] = 0x83; // ADD ESP,124. 最初に調整したス...
code[qc++] = 0xc4;
code[qc++] = 0x7c;
code[qc++] = 0x61; // POPAD.
code[qc++] = 0xc3; // RET.
func = (void *) code;
func();
exit(0);
err:
printf("syntax error : %s %s %s %s\n", t[pc], t[pc +...
exit(1);
}
-結局どこを改造したのかというと、代入、加算、while、print...
-これにより、処理が以下のように単純化されます。
|処理|普通の変数の場合|レジスタ変数の場合|
|i = 3;|[2命令] MOV(EAX,[....]); MOV([....],EAX);|[1命令]...
|i = i + 5;|[4命令] MOV(EAX,[...]); MOV(ECX,[...]); ADD(E...
-ということで、TJ-03aと比較して4倍くらい速くなります(1億...
-でもgccはさらに速いコードを生成しています。ということで...
** 次回に続く
-次回: [[text0016]]
*こめんと欄
#comment
ページ名: