日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > C編譯器剖析_6.3.3 匯編代碼生成_為跳轉指令產生匯編代碼

C編譯器剖析_6.3.3 匯編代碼生成_為跳轉指令產生匯編代碼

來源:程序員人生   發布時間:2015-06-19 08:43:41 閱讀次數:3350次

6.3.3        為跳轉指令產生匯編代碼

    在這1小節中,我們要為“有條件跳轉”、“無條件跳轉”和“間接跳轉”產生相應的匯編指令。中間指令的4元式以下所示:

         <運算符opcode,目的操作數DST,源操作數SRC1,源操作數SRC2>

   (1) 有條件跳轉,例如“if (a <= b) goto BB2;”,4元式為:

            <JLE,BB2,a,b>

            ////////對應的匯編代碼//////////

            movl  a, %eax    //把SRC1的值暫存在寄存器eax中   

            cmpl b, %eax     //比較eax和b的大小

            jle   .BB2       //進行有條件跳轉

   (2) 無條件跳轉,例如“goto  BB3;”,4元式為:

            <JMP,BB3,NULL,NULL>

            ////////////對應的匯編代碼///////////////

            jmp          .BB3

   (3) 間接跳轉,例如“goto (BB4,BB5,BB6)[t0];”,在翻譯switch語句時會產生間接跳轉指令,其4元式為:

            <IJMP,[BB4,BB5,BB6,NULL],t0,NULL>

            ////////////對應的匯編代碼///////////////

             .data

swtchTable1: .long         .BB4

             .long         .BB5

             .long         .BB6             

.text

         jmp*swtchTable1(,%eax,4)

     由于跳轉指令位于基本塊的最末尾,我們在第6.2節的“圖6.2.3 EmitBBlock()”中,已對x87棧頂寄存器做過回寫操作。在本小節,我們還要中調用ClearRegs函數,對x86 CPU中的寄存器進行回寫,如圖6.3.7第7行、第26行和第54行所示??刂屏餍袑㈦S著跳轉指令的履行而進入另外一個基本塊,而UCC編譯器僅在同1基本塊內對公共子表達式進行重用,因此,即便跳轉指令里的操作數DST、SRC1和SRC2是臨時變量,我們沒有必要為其“長時間”分配寄存器,換言之,我們不會調用在前面的章節中介紹過的AllocateReg函數,而是調用如圖6.3.7第13行所示的PutInReg函數,把操作數SRC1的值暫存到某個寄存器中。

    圖6.3.7第1至30行的EmitBranch函數用于為“有條件跳轉”產生匯編代碼,當操作數是浮點數時,我們在第8行調用EmitX87Branch函數來處理。當操作數是整數時,我們會在第11行做進1步判斷。由于常數會以“立即數”的情勢存在于代碼區中,當程序運行時,CPU會從代碼區里預讀機器指令,從而把立即數也加載入CPU,因此當操作數SRC2是常數時,我們可以沒必要把SRC1的值加載到寄存器中,這不會違背“同1條X86匯編指令的兩個操作數不可以都在內存中”的尋址要求。這意味著我們可以生成形如“cmpl  $3, a”的比較指令,但不可以生成形如“cmpl  b, a”的比較指令。圖6.3.7第11至14行會在“SRC2存在且SRC2不是常數時”,通過第13行調用的PutInReg函數,把SRC1的值加載到某個寄存器中。第17行判斷SRC1的值是不是在寄存器中,如果已載入寄存器,我們可在第18行把中間指令里的源操作數SRC1改成SRC1->reg,以后在便可生成形如“cmpl  b, %eax”的比較指令。第28行調用PutASMCode函數來產生比較和跳轉指令,形如“cmpl  b, %eax;jle .BB2 ”。


圖6.3.7  EmitBranch()和EmitJump()

   圖6.3.7第31至39行的EmitX87Branch用于處理浮點數的有條件跳轉,我們會在第34行先把操作數SRC1加載到x87棧頂寄存器中,然后在第37行生成浮點數比較和跳轉的指令,形如第35至36行的模板所示。我們已在“1.5  結合C語言來學匯編”介紹過這些指令,這里不再重復。圖6.3.7第50至56行的函數EmitJump會為無條件跳轉生成匯編代碼。

   接下來,我們來討論1下為“間接跳轉”產生匯編代碼的函數EmitIndirectJump,如圖6.3.8所示。圖6.3.8第7行調用PutInReg函數把操作數SRC1加載到寄存器中,第10行用于產生“.data”,表示接下來的內容為數據區,第11至17行創建1個名稱形如“swtchTable1”的符號對象,第23至33行會在數據區中創建跳轉表,形如第19至21行所示。第36行輸出“.text”,表示接下來的內容為代碼區。由于已在第7行把SRC1加載到寄存器reg中,我們便可在匯編指令中使用該寄存器的名稱,為此我們要在第37行把中間指令的SRC1改成相應的寄存器。第38行調用ClearRegs對x86 CPU中的寄存器進行了必要的回寫,第41行調用PutASMCode產生了形如“jmp*swtchTable1(,%eax,4)”的匯編指令。


圖6.3.8  EmitIndirectJump()

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 久久成人免费网 | 韩国色综合 | 狠狠艹 | 最近更新2019中文在线视频 | 免费污污网站 | 亚洲天堂成人 | 精品一区在线播放 | 久久久一区二区三区 | 国产精品免费视频观看 | 国产成人精品免高潮在线观看 | 久久精品观看 | 欧美色综合天天久久综合精品 | 国产成人毛片 | 999免费在线视频 | 7777久久香蕉成人影院 | 青青草青青操 | 久久久精品欧美一区二区 | 日韩精品一区在线 | 91精品国产入 | 国产伦精品一区二区三区免费 | 成人永久免费视频 | 国产4区| 日日夜夜狠狠 | 国内精品久久久久久中文字幕 | 国产福利小视频 | 精品视频在线免费观看 | 国产精品久久久久久在线 | 日本一区二区三区四区在线观看 | 精品视频在线看 | 成人午夜精品一区二区三区 | 日本久久91 | 高清国产一区二区三区 | aa久久 | 亚洲一区成人 | 黄a视频| 国产精品爱久久久久久久 | 亚洲高清在线视频 | av在线精品 | 91在线| 国产精品成人一区二区三区夜夜夜 | 一区二区三区91 |