多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

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

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

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

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行所示。控制流行將隨著跳轉指令的履行而進入另外一個基本塊,而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()

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 中文第一页 | 国产精品无码久久久久 | 波多野结衣福利 | 91视频影院 | 中文字幕日韩精品一区口 | 一本本久综合久久爱 | 国产免费一级高清淫曰本片 | 国产精品爱久久久久久久三级 | 成人性生活视频 | 日本专区 | 搞av网| 亚洲综合欧美在线 | 在线成h人视频网站免费观看 | 亚洲天堂网视频 | 国产青草亚洲香蕉精品久久 | 免费观看老外特级毛片 | 亚洲精品久久久成人 | 伊人久久综合网站 | 亚洲国产精品嫩草影院久久 | 精品成人一区二区三区免费视频 | 国内亚州视频在线观看 | 亚洲成人影院在线 | 免费黄色网址网站 | 国产专区在线视频 | 精品欧美一区二区三区 | 亚洲天堂一区二区 | a4yy私人毛片 | 欧美三级一区 | 亚欧毛片| 欧美free嫩交videoxxx | 多人做人爱视频大全在线观看 | 成人一区专区在线观看 | 亚欧成人毛片一区二区三区四区 | 在线观看www视频 | 亚洲性夜 | 尤物在线视频 | 国产三级高清 | 欧美日韩一区二区在线视频播放 | 欧美18+| 精品伊人久久久久网站 | 国产亚洲精品观看91在线 |