| MovRI(r,imm); | R0~R7に即値定数immを代入、Rx=imm; |
| MovAI(a,imm); | A0~A7に即値定数immを代入、Ax=imm; |
| LodRMd(r,base,disp); | Rxの値をメモリから読み込みます(load)、base=ベースレジスタAx, disp=即値ディスプレイスメント、Rx=[Ax+disp]; |
| StoRMd(r,base,disp); | Rxの値をメモリに書き込みます(store)、[Ax+disp]=Rx; |
| LodAMd(a,base,disp); | Ax=[Ax+disp]; |
| StoAMd(a,base,disp); | [Ax+disp]=Ax; |
| AddRI(r,imm); | Rxに即値定数immを加算、Rx+=imm; |
| AddAI(a,imm); | Ax+=imm; |
| AddRR(r0,r1); | r0+=r1; |
| SubRI(r,imm); | Rx-=imm; |
| SubAI(a,imm); | Ax-=imm; |
| SubRR(r0,r1); | r0-=r1; |
| CmpJleRII(r,imm,lab); | Rxを即値定数immと比較して結果に応じてラベル番号labにジャンプする、if(Rx<=imm)goto lab; |
| CmpJccRII(r,imm,lab); | 他にもJe/Jne/Jl/Jge/Jgがあるが、書くのが面倒なので省略 |
| LbI(lab); | ラベル宣言、JmpやCalの飛び先指定に使用 |
| JmpI(lab); | 無条件分岐、goto lab; |
| JmpA(a); | 無条件分岐、goto Ax; |
| CalII(lab,tmp); | サブルーチンのCALL命令、tmpは内部処理用のラベル番号(欄外に補足説明あり)、call lab; |
| Ret(); | サブルーチンからのリターン、return; |
int fib(int i)
{
if (i <= 1) return i;
return fib(i - 2) + fib(i - 1);
}
int main()
{
printf("fib(46)=%d\n", fib(46));
return 0;
}LbI(1); // fib.
SubAI(SP,16);
StoAMd(RP,SP,8); // RPを保存.
LodRMd(R0,SP,16); // R0=引数.
CmpJleRII(R0,1,5);
LbI(2);
SubRI(R0,2); // fib(i-2)
StoRMd(R0,SP,0);
CalII(1,3);
StoRMd(R0,SP,12); // 結果を保存.
LodRMd(R0,SP,16); // fib(i-1)
SubRI(R0,1);
StoRMd(R0,SP,0);
CalII(1,4);
LodRMd(R1,SP,12); // 結果の加算.
AddRR(R0,R1);
LbI(5);
LodAMd(RP,SP,8); // RPの復元.
AddAI(SP,16);
Ret();
LbI(6); // main
SubAI(SP,8);
MovRI(R0,46); // fib(46)
StoRMd(R0,SP,0);
CalII(1,7);
// この時点のR0に答えが入っている.#include <stdio.h>
#include <stdlib.h>
#define kharcMain_bgn() int R0,R1,RP; vJmp: switch (PC) {
#define kharcMain_end() }
#define MovRI(r,i) r=i
#define MovAI(a,i) a=i
#define LodRMd(r,b,d) r=*(int*)&m[b+d]
#define StoRMd(r,b,d) *(int*)&m[b+d]=r
#define LodAMd(a,b,d) a=*(int*)&m[b+d]
#define StoAMd(a,b,d) *(int*)&m[b+d]=a
#define AddRI(r,i) r+=i
#define AddAI(a,i) a+=i
#define AddRR(r0,r1) r0+=r1
#define SubRI(r,i) r-=i
#define SubAI(a,i) a-=i
#define CmpJleRII(r,i,l) if(r<=i)goto lb##l
#define LbI(l) lb##l: case l:
#define CalII(l,t) MovAI(RP,t); goto lb##l; LbI(t)
#define Ret() PC=RP; goto vJmp
int kharcMain(int PC, int SP, char *m)
{
kharcMain_bgn();
(上記のコード:prog2)
kharcMain_end();
return R0;
}
int main()
{
char *mem = malloc(1024);
int R0 = kharcMain(6, 1024, mem);
printf("R0=%d\n", R0);
return 0;
}