freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

樹(shù)遍歷解釋器基于棧與基于寄存器大雜燴-文庫(kù)吧

2025-04-17 21:14 本頁(yè)面


【正文】 F 文件里就包含有 AS 字節(jié)碼 (ActionScript Byte Code, ABC)。等到 FlashPlayer 去執(zhí)行 SWF 文件,或者說(shuō)等到 AVM2(ActionScript Virtual Machine 2)去執(zhí)行 ABC時(shí),又有解釋器和 JIT 編譯器兩種實(shí)現(xiàn)。這種需要讓用戶顯式進(jìn)行編譯步驟的語(yǔ)言,到底是不是 解釋型語(yǔ)言 呢 ?呵呵。所以我一直 覺(jué)得 編譯型語(yǔ)言 跟 解釋型語(yǔ)言 的說(shuō)法太模糊,不太好。有興趣想體驗(yàn)一下從命令行編譯 裸 的 AS3文件得到 ABC文件,再?gòu)拿钚姓{(diào)用 AVM2 去執(zhí)行 ABC 文件的同學(xué),可以從這帖下載我之前從源碼編譯出來(lái)的 AVM2,自己玩玩看。例如說(shuō)要編譯一個(gè)名為 的文件,用下列命令: Command prompt 代碼 javajar 就是用 ASC將 編譯,得到 。接著用: Command prompt 代碼 avmplus 就是用 AVM2 去執(zhí)行程序了。很生動(dòng)的體現(xiàn)出 編譯器 +虛擬機(jī) 的實(shí)現(xiàn)方式。這個(gè) 裸 的 AVM2 沒(méi)有帶 Flash 或Flex 的類庫(kù),能用的函數(shù)和類都有限。不過(guò) AS3語(yǔ)言實(shí)現(xiàn)是完整的??梢杂胮rint()函數(shù)來(lái)向標(biāo)準(zhǔn)輸出流寫(xiě)東西。 Well…其實(shí)寫(xiě) Java 程序不也是這樣么 ?現(xiàn)在也確實(shí)還有很多人把 Java 稱為 解釋型語(yǔ)言 ,完全無(wú)視 Java 代碼通常是經(jīng)過(guò)顯式編譯步驟才得到 .class 文件,而有些 JVM 是采用純 JIT 編譯方式實(shí)現(xiàn)的,內(nèi)部沒(méi)解釋器,例如 Jikes RVM。我愈發(fā)感到 解釋型語(yǔ)言 是個(gè)應(yīng)該避開(kāi)的用語(yǔ) =_=關(guān)于虛擬機(jī),有本很好的書(shū)絕對(duì)值得一讀,《虛擬機(jī) 系統(tǒng)與進(jìn)程的通用平臺(tái)》 (Virtual Machines: Versatile Platforms for Systems and Processes)。國(guó)內(nèi)有影印版也有中文版,我是讀了影印版,不太清楚中文版的翻譯質(zhì)量如何。據(jù)說(shuō)翻譯得還行,我無(wú)法印證。 基于棧與基于寄存器的指令集架構(gòu)用 C 的語(yǔ)法來(lái)寫(xiě)這么一個(gè)語(yǔ)句: C 代碼 a=b+c;如果把它變成這種形式: add a,b,c 那看起來(lái)就更像機(jī)器指令了,對(duì)吧 ?這種就是 所謂 三地址指令 (3address instruction),一般形式為: op dest,src1,src2 許多操作都是二元運(yùn)算 +賦值。三地址指令正好可以指定兩個(gè)源和一個(gè)目標(biāo),能非常靈活的支持二元操作與賦值的組合。 ARM 處理器的主要指令集就是三地址形式的。 C里要是這樣寫(xiě)的話: C 代碼 a+=b;變成: add a,b 這就是所謂 二地址指令 ,一般形式為: op dest,src 它要支持二元操作,就只能把其中一個(gè)源同時(shí)也作為目標(biāo)。上面的add a,b 在執(zhí)行過(guò)后,就會(huì)破壞 a原有的值,而 b 的值保持不變。 x86 系列的 處理器就是二地址形式的。上面提到的三地址與二地址形式的指令集,一般就是通過(guò) 基于寄存器的架構(gòu) 來(lái)實(shí)現(xiàn)的。例如典型的 RISC 架構(gòu)會(huì)要求除 load 和store 以外,其它用于運(yùn)算的指令的源與目標(biāo)都要是寄存器。顯然,指令集可以是任意 n 地址 的, n屬于自然數(shù)。那么一地址形式的指令集是怎樣的呢 ?想像一下這樣一組指令序列: add 5sub 3 這只指定了操作的源,那目標(biāo)是什么 ?一般來(lái)說(shuō),這種運(yùn)算的目標(biāo)是被稱為 累加器 (accumulator)的專用寄存器,所有運(yùn)算都靠更新累加器的狀態(tài)來(lái)完成。那么上面兩條指令用 C來(lái)寫(xiě)就類 似: C 代碼 acc+=5; acc=3;只不過(guò) acc是 隱藏 的目標(biāo)。基于累加器的架構(gòu)近來(lái)比較少見(jiàn)了,在很老的機(jī)器上繁榮過(guò)一段時(shí)間。那 n 地址 的 n如果是 0的話呢 ?看這樣一段 Java 字節(jié)碼: Java bytecode 代碼 iconst_1iconst_2iaddistore_0 注意那個(gè) iadd(表示整型加法 )指令并沒(méi)有任何參數(shù)。連源都無(wú)法指定了,零地址指令有什么用 ?零地址意味著源與目標(biāo)都是隱含參數(shù),其實(shí)現(xiàn)依賴于一種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu) 沒(méi)錯(cuò),就是棧。上面的 iconst_ iconst_2 兩條指令,分別向一個(gè)叫 做 求值棧(evaluation stack,也叫做 operand stack操作數(shù)棧 或者 expression stack表達(dá)式棧 )的地方壓入整型常量 2。 iadd 指令則從求值棧頂彈出 2個(gè)值,將值相加,然后把結(jié)果壓回到棧頂。 istore_0 指令從求值棧頂彈出一個(gè)值,并將值保存到局部變量區(qū)的第一個(gè)位置 (slot 0)。零地址形式的指令集一般就是通過(guò) 基于棧的架構(gòu) 來(lái)實(shí)現(xiàn)的。請(qǐng)一定要注意,這個(gè)棧是指 求值棧 ,而不是與系統(tǒng)調(diào)用棧 (system call stack,或者就叫 system stack)。千萬(wàn)別弄混了。有些虛擬機(jī)把求值棧實(shí)現(xiàn)在系統(tǒng)調(diào)用棧上,但兩者概念上不是一個(gè)東西。由于指令的源與目標(biāo)都是隱含的,零地址指令的 密度 可以非常高 可以用更少空間放下更多條指令。因此在空間緊缺的環(huán)境中,零地址指令是種可取的設(shè)計(jì)。但零地址指令要完成一件事情,一般會(huì)比二地址或者三地址指令許多更多條指令。上面 Java 字節(jié)碼做的加法,如果用 x86指令兩條就能完成了: X86 asm 代碼 mov eax,1add eax,2(好吧我犯規(guī)了, istore_0 對(duì)應(yīng)的保存我沒(méi)寫(xiě)。但假如局部變量比較少的話也不必把 EAX 的值保存到調(diào) 用棧上,就這樣吧 =_=其實(shí)就算把結(jié)果保存到棧上也就是多一條指令而已… )一些比較老的解釋器,例如 CRuby 在 引入 YARV 作為新的 VM之前的解釋器,還有SquirrleFish 之前的老 JavaScriptCore,它們內(nèi)部是樹(shù)遍歷式解釋器;解釋器遞歸遍歷樹(shù),樹(shù)的每個(gè)節(jié)點(diǎn)的操作依賴于解釋其各個(gè)子節(jié)點(diǎn)返回的值。這種解釋器里沒(méi)有所謂的求值棧,也沒(méi)有所謂的虛擬寄存器,所以不適合以 基于棧 或 基于寄存器 去描述。而像 V8 那樣直接編譯 JavaScript 生成機(jī)器碼,而不通過(guò)中間的字節(jié)碼的中間表示的 JavaScript 引擎,它內(nèi)部有虛擬寄存器的概念,但那只是普通 native 編譯器的正常組成部分。我覺(jué)得也不應(yīng)該用 基于棧 或 基于寄存器 去描述它。 V8 在內(nèi)部也用了 求值棧 (在 V8 里具體叫 表達(dá)式棧 )的概念來(lái)簡(jiǎn)化生成代碼的過(guò)程,使用所謂 虛擬棧幀 來(lái)記錄局部變量與求值棧的狀態(tài);但在真正生成代碼的時(shí)候會(huì)做窺孔優(yōu)化,消除冗余的 push/pop,將許多對(duì)求值棧的操作轉(zhuǎn)變?yōu)閷?duì)寄存器的操作,以此提高代碼質(zhì)量。于是最終生成出來(lái)的代碼看起來(lái)就不像是基于棧的代碼了。關(guān)于 JavaScript 引擎的實(shí)現(xiàn)方式,下文會(huì)再提到。 基于棧與基于 寄存器架構(gòu)的 VM,用哪個(gè)好 ?如果是要模擬現(xiàn)有的處理器,那沒(méi)什么可選的,原本處理器采用了什么架構(gòu)就只能以它為源。但 HLL VM 的架構(gòu)通??梢宰杂蓸?gòu)造,有很大的選擇余地。為什么許多主流 HLL VM,諸如 JVM、 CLI、 CPython、 CRuby 等,都采用了基于棧的架構(gòu)呢 ?我覺(jué)得這有三個(gè)主要原因:實(shí)現(xiàn)簡(jiǎn)單由于指令中不必顯式指定源與目標(biāo), VM可以設(shè)計(jì)得很簡(jiǎn)單,不必考慮為臨時(shí)變量分配空間的問(wèn)題,求值過(guò)程中的臨時(shí)數(shù)據(jù)存儲(chǔ)都讓求值棧包辦就行。更新:回帖中 cscript 指出了這句不太準(zhǔn)確,應(yīng)該是針對(duì)基于棧架構(gòu)的指 令集生成代碼的編譯器更容易實(shí)現(xiàn),而不是 VM 更容易實(shí)現(xiàn)。該 VM 是為某類資源非常匱乏的硬件而設(shè)計(jì)的這類硬件的存儲(chǔ)器可能很小,每一字節(jié)的資源都要節(jié)省。零地址指令比其它形式的指令更緊湊,所以是個(gè)自然的選擇??紤]到可移植性處理器的特性各個(gè)不同:典型的 CISC處理器的通用寄存器數(shù)量很少,例如 32位的 x86 就只有 8個(gè) 32位通用寄存器 (如果不算EBP和 ESP那就是 6個(gè),現(xiàn)在一般都算上 );典型的 RISC 處理器的各種寄存器數(shù)量多一些,例如 ARM有 16個(gè) 32位通用寄存器, Sun的 S
點(diǎn)擊復(fù)制文檔內(nèi)容
黨政相關(guān)相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1