int func(int i)
{
asm { LodRMd(R0,SP,$i); AddRI(R0,3); } // R0=i+3;
}LbI(1); // func() SubAI(SP,8); StoAMd(RP,SP,0); // RP値を保存している(とりあえず今は無条件でやっている). LodRMd(R0,SP,8); AddRI(R0,3); // (ここはasmの中身)$iが8に置換されている. LodAMd(RP,SP,0); // RP値を復元している. AddAI(SP,8); Ret();
void main()
{
params(1); // このmain内で行われる関数呼び出しは、引数が最大で1つだという意味(もしインラインアセンブラ内で関数呼び出ししないなら、この記述はいらない).
asm {
MovRI(R0,46); StoRMd(R0,SP,0); CalII($fib,@lb0:); // R0 = fib(46);
return R0;
}
}
int fib(int i)
{
int tmp;
params(1);
asm {
LodRMd(R0,SP,$i); CmpJleRII(R0,1,@skip); // if (i <= 1) goto skip;
SubRI(R0,2); StoRMd(R0,SP,0); CalII($fib,@lb0:); StoRMd(R0,SP,$tmp); // tmp = fib(i-2);
LodRMd(R0,SP,$i); SubRI(R0,1); StoRMd(R0,SP,0); CalII($fib,@lb1:); // R0 = fib(i-1);
LodRMd(R1,SP,$tmp); AddRR(R0,R1); // R0 += tmp;
LbI(@skip:);
}
}LbI(4); // fib()
SubAI(SP,16);
StoAMd(RP,SP,12);
LodRMd(R0,SP,16); CmpJleRII(R0,1,7); // if (i <= 1) goto skip;
SubRI(R0,2); StoRMd(R0,SP,0); CalII(4,5); StoRMd(R0,SP,8); // tmp = fib(i-2);
LodRMd(R0,SP,16); SubRI(R0,1); StoRMd(R0,SP,0); CalII(4,6); // R0 = fib(i-1);
LodRMd(R1,SP,8); AddRR(R0,R1); // R0 += tmp;
LbI(7); // skip:
LodAMd(RP,SP,12);
AddAI(SP,16);
Ret();{ [SP+0:引数用の領域8バイト] [SP+8:変数tmp] [SP+12:RP保存領域] } [SP+16:引数i]void main()
{
fib(46); asm { return R0; }
}
int fib(int i)
{
asm { LodRMd(R0,SP,$i); CmpJleRII(R0,1,@skip); }
i = fib(i - 2) + fib(i - 1); // ← ここがかっこいい!
asm { LbI(@skip:); }
return i;
}LbI(4); // fib()
SubAI(SP,24);
StoAMd(RP,SP,20);
LodRMd(R0,SP,24); CmpJleRII(R0,1,7); // (ここはasmの中身)
LodRMd(R0,SP,24); // ムダ
SubRI(R0,2);
StoRMd(R0,SP,8); // ムダ
LodRMd(R0,SP,8); // ムダ
FreI(8);
StoRMd(R0,SP,0);
CalII(4,5);
StoRMd(R0,SP,8);
LodRMd(R0,SP,24);
SubRI(R0,1);
StoRMd(R0,SP,12); // ムダ
LodRMd(R0,SP,12); // ムダ
FreI(12);
StoRMd(R0,SP,0);
CalII(4,6);
StoRMd(R0,SP,12);
LodRMd(R0,SP,8);
LodRMd(R1,SP,12);
AddRR(R0,R1);
StoRMd(R0,SP,16);
FreI(8);
FreI(12);
LodRMd(R0,SP,16);
StoRMd(R0,SP,24);
FreI(16);
LbI(7); LodRMd(R0,SP,24); // (ここはasmの中身)
JmpI(8); // ムダ
LbI(8); // fib().ret:
LodAMd(RP,SP,20);
AddAI(SP,24);
Ret();
// { [SP+0:引数用の領域8バイト] [SP+8:内部生成した一時変数tmp0] [SP+12:tmp1] [SP+16:tmp2] [SP+20:RP保存領域] } [SP+24:引数i]int func()
{
int i, j, k;
i = j = k = 1 + 2 * 3;
i = (j = 4) + 5;
}LbI(1); // func() SubAI(SP,16); StoAMd(RP,SP,12); MovRI(R0,7); // 1+2*3 をコンパイル時に計算して 7 にしている. StoRMd(R0,SP,8); // k MovRI(R0,7); StoRMd(R0,SP,4); // j MovRI(R0,7); StoRMd(R0,SP,0); // i MovRI(R0,4); StoRMd(R0,SP,4); // j MovRI(R0,9); // 4+5 をコンパイル時に計算して 9 にしている. StoRMd(R0,SP,0); // i LbI(2); // func().ret: LodAMd(RP,SP,12); AddAI(SP,16); Ret();
void main()
{
fib(46); asm { return R0; }
}
int fib(int i)
{
if (i <= 1) goto skip;
i = fib(i - 2) + fib(i - 1);
skip:
return i;
}int main()
{
int i;
for (i = 0x20; i <= 0x7e; i++) {
putchar(i);
}
putchar(0x0a);
asm { return 0; }
}
void putchar(int c)
{
asm { LodRMd(R0,SP,$c); putchar(R0); }
}int main()
{
int i;
for (i = 1; i <= 100; i++) {
if (i % 15 == 0) {
asm { printf("FizzBuzz\n"); }
} else if (i % 3 == 0) {
asm { printf("Fizz\n"); }
} else if (i % 5 == 0) {
asm { printf("Buzz\n"); }
} else {
asm { LodRMd(R0,SP,$i); printf("%d\n", R0); }
}
}
asm { End(); }
}struct KharcBinInst { unsigned char op, prm[3]; int imm; };| R0 | R1 | R2 | SP | RP | |
| EAX | ECX | EDX | EBP | EBX |
| 1.kccに内蔵させた自作のエミュレータで実行 | 191.798[sec] |
| 2.kccに内蔵させた自作のエミュレータで実行(改良版) | 128.766[sec] |
| 3.kccに内蔵させた自作のJITコンパイラで実行 | 15.246[sec] |
| 4.kccが出力したアセンブラをgccでコンパイルして実行 | 12.715[sec] |
| 5.fibのプログラムをそのままgccでコンパイルして実行 | 4.577[sec] |