寄存器計(jì)算機(jī)是目前最流行的機(jī)器體系結(jié)構(gòu)之一。
- 效率很高
- 機(jī)器體系結(jié)構(gòu)規(guī)整
機(jī)器基于寄存器架構(gòu):
- 典型的有16、32或更多個(gè)寄存器,所有操作都在寄存器中進(jìn)行
- 訪(fǎng)存都通過(guò)load/store進(jìn)行,內(nèi)存不能直接運(yùn)算
寄存器計(jì)算機(jī)Reg的結(jié)構(gòu)
- 內(nèi)存,存放溢出的變量(溢出是指寄存器放不下的變量)
- 寄存器,進(jìn)行運(yùn)算的空間,假設(shè)有無(wú)限多個(gè)
- 執(zhí)行引擎,指令的執(zhí)行
寄存器計(jì)算機(jī)的指令集(ISA)
指令的語(yǔ)法
s -> ?movn n, r? ? ? ? ? ? ? ? 將一個(gè)立即數(shù)賦值給一個(gè)寄存器(數(shù)據(jù)移動(dòng))
? -> ?mov r1, r2? ? ? ? ? ? ? ? 將一個(gè)寄存器的值賦值給另一個(gè)寄存器(數(shù)據(jù)移動(dòng))
? -> ?load [x], r? ? ? ? ? ? ? ? ?把內(nèi)存中x的值讀入到寄存器r中(訪(fǎng)存)
? -> ?store r, [x]? ? ? ? ? ? ? ? 把一個(gè)數(shù)據(jù)從寄存器中寫(xiě)入到內(nèi)存中(訪(fǎng)存)
? -> ?add r1, r2, r3? ? ? ? ? ?r3 = r1 + r2(算術(shù)運(yùn)算)
? -> ?sub r1, r2, r3? ? ? ? ? ?r3 = r1 -?r2(算術(shù)運(yùn)算)
? -> ?times r1, r2, r3? ? ? ??r3 = r1 *?r2(算術(shù)運(yùn)算)
? -> ?div r1, r2, r3? ? ? ? ? ??r3 = r1 /?r2(算術(shù)運(yùn)算)
注:[x]表示這樣一個(gè)x是在內(nèi)存當(dāng)中的
變量的寄存器分配偽指令
Reg機(jī)器只支持一種數(shù)據(jù)類(lèi)型int,并且給變量x分配寄存器的偽指令是
.int x
在代碼生成階段,假設(shè)Reg機(jī)器上有無(wú)限多個(gè)寄存器。
- 因此每個(gè)聲明變量和臨時(shí)變量都會(huì)占用一個(gè)(虛擬)寄存器
- 把虛擬寄存器分配到物理寄存器的過(guò)程稱(chēng)為寄存器分配。
遞歸下降代碼生成算法
從C--到Reg
注意:在棧式計(jì)算機(jī)中,每一個(gè)函數(shù)都是void類(lèi)型,而此處寄存器計(jì)算機(jī)Gen_E(E)的返回值類(lèi)型為R_t(寄存器類(lèi)型)。
表達(dá)式的代碼生成
不變式:表達(dá)式的值在函數(shù)返回的寄存器中
R_t Gen_E(E e)
{
switch (e)
{
case n:
r = fresh(); // 返回唯一的寄存器編號(hào)
emit("movn n, r");
return r;
case id:
r = fresh();
emit("mov id, r");
return r;
case true:
r = fresh();
emit("movn 1, r");
return r;
case false:
r = fresh();
emit("movn 0, r");
return r;
case e1 + e2:
r1 = Gen_E(e1);
r2 = Gen_E(e2);
r3 = fresh();
emit("add r1, r2, r3");
return r3;
case e1 && e2:
r1 = Gen_E(e1);
r2 = Gen_E(e2);
r3 = fresh();
emit("and r1, r2, r3");
return r3; // 非短路
default:
break;
}
}
語(yǔ)句的代碼生成
Gen_S(S s)
{
switch (s)
{
case id = e:
r = Gen_E(e);
emit("mov r, id"); // 假設(shè)此處id也在寄存器中
break;
case printi(e):
r = Gen_E(e);
emit("printi r");
break;
case printb(e):
r = Gen_E(e);
emit("printb r");
break;
default:
break;
}
}
類(lèi)型的代碼生成
不變式:只生成.int 類(lèi)型
Gen_T(T t)
{
switch (t)
{
case int:
emit(".int");
break;
case bool:
emit(".int");
break;
default:
break;
}
}
變量聲明的代碼生成
不變式:只生成.int 類(lèi)型
Gen_D(T id; D)
{
Gen_T(T);
emit(" id");
Gen_D(D);
}
程序的代碼生成
不變式:只生成.int 類(lèi)型
Gen_P(D S)
{
Gen_D(D);
Gen_S(S);
}
tip:將x = 1 + 2 + 3 + 4 畫(huà)成抽象語(yǔ)法樹(shù),就可以理解對(duì)應(yīng)產(chǎn)生的9條匯編級(jí)指令了。
如何運(yùn)行生成的代碼?
1、寫(xiě)一個(gè)虛擬機(jī)(解釋器),這個(gè)虛擬機(jī)上就有無(wú)限個(gè)寄存器,我們可以用單鏈表存放寄存器,這個(gè)單鏈表可以無(wú)限長(zhǎng)。
2、在真實(shí)的物理機(jī)器上運(yùn)行:需進(jìn)行寄存器分配
我們有無(wú)限多個(gè)虛擬寄存器(r1, ..., rn),但一臺(tái)物理機(jī)上只有k1-km個(gè)寄存器,那么我們就需要把這些寄存器虛擬的映射到實(shí)際的物理機(jī)器上,如果還不夠用的話(huà),那么就需要有一些虛擬寄存器放到內(nèi)存里(前面提到的“溢出”)
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-403975.html
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-403975.html
到了這里,關(guān)于代碼生成- 寄存器計(jì)算機(jī)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!