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

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > C編譯器剖析_6.3.2 匯編代碼生成_由EmitAssign函數產生算術運算的匯編代碼

C編譯器剖析_6.3.2 匯編代碼生成_由EmitAssign函數產生算術運算的匯編代碼

來源:程序員人生   發布時間:2015-08-18 08:24:00 閱讀次數:3425次

6.3.2  由EmitAssign函數產生算術運算的匯編代碼

   在這1小節中,我們要討論的中間指令形如“t1: a+b;”或“t2:&number”,這些指令用于進行1元或2元算術運算,并把運算結果保存在臨時變量t1或t2中。UCC中間指令的格式以下所示:

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

         <ADD,t1,a,b>           //  t1: a+b;

         <ADDR,t2,number,NULL>  // t2: &number;

    由于在1條x86匯編指令中,最多只允許出現2個操作數,而中間指令“DST:SRC1+SRC2”有3個操作數,我們需要產生多條x86匯編指令來實現該中間指令。在匯編指令中,整數加法運算對寄存器沒甚么特別要求,我們可按以下步驟來處理:

   (1) 調用AllocateReg函數順次為SRC1、SRC2和DST分配寄存器。DST是用于保存運算結果的臨時變量,必定可分配到1個寄存器,無妨記為R0。而如果SRC1和SRC2不是臨時變量,則沒有分配到寄存器。

   (2) 若DST和SRC1對應的寄存器不1樣,我們可產生1條movl指令,把SRC1的值傳送到寄存器R0中。

   (3) 產生加法指令,進行SRC2和R0的加法,并把結果存于寄存器R0中。

   按這樣的思路,我們可為“t1 : a+b;”產生以下匯編代碼:

movl  a,  %eax

addl  b,  %eax

    而形如“t2: &number”的中間指令只有兩個操作數,在上述第(1)步中,我們就沒必要為

SRC2分配寄存器,其他的步驟類似,我們可為“t2: &number”產生以下匯編代碼:

         leal  a,  %ecx

    不過,有些x86匯編指令對寄存器有特定的要求,比如整數的乘法運算就要求源操作數SRC1的值被加載到寄存器eax中。而整數的除法運算或取余運算,要求源操作數SRC1的值被加載到eax中,如果要進行的是有符號數的除法運算,則寄存器edx的所有位都被設置為SRC1的符號位;如果要進行的是無符號數的除法運算,則寄存器edx被置為全0。例如我們可為中間指令“t3: a /b;”產生以下匯編代碼,其中a和b為有符號整數。

         movl a, %eax   //把SRC1加載到eax

         cdq            //把符號位擴大到edx寄存器

         idivl  b    //進行除法運算[edx: eax] / SRC2,商存于eax,余數存于edx,

                     //此時eax中的值就是臨時變量t3的值

     在x86“左移或右移”的匯編指令中,如果要把左移或右移的位數寄存于寄存器中,則必須使用單字節寄存器cl,以下所示:

         int  a, c;  char  len = 3;

         c = a <<len;

         ////中間代碼//////////////

         t4 : (int)(char)len;       //把char提升為int

         t5 : a << t4;

         c = t5;

     對應的匯編代碼以下所示,我們可以看到,在匯編指令“shll  %cl,%edx”中,我們是用單字節寄存器cl來寄存操作數len的值。

         movsbl  len,  %eax      // t4 : (int)(char)len;

         movl  %eax,  %ecx       //t5: a << t4

         movl  a,  %edx

         shll  %cl,  %edx

         movl  %edx,  c          // c = t5;

     有了這些基礎后,我們可以來討論1下“為算術運算生成匯編代碼”的函數EmitAssign,如圖6.3.5所示。第47至56行用于處理對寄存器沒有特別要求的2元運算,形如“DST:SRC1+SRC2;”。第44至45行用于處理形如“DST: ~SRC1”的1元運算,此時我們沒必要為SRC2分配寄存器。第33至43行用于為左移或右移指令里的SRC2分配寄存器ecx,并在第39行把SRC2加載寄存器ecx,以后在第41行把SRC2改成單字節寄存器cl,即4字節寄存器ecx的低8位。


圖6.3.5  EmitAssign()

     圖6.3.5第8至32行用于為整數乘法、除法和取余運算產生匯編指令,第11至16行把SRC1的值暫存于寄存器eax中,第17行把edx寄存器的值回寫到內存中,我們會在[edx:eax]中寄存經符號位擴大后的SRC1。第19至24行用于為SRC2分配必要的寄存器,第26行產生匯編指令來進行乘法或除法運算,以后寄存器eax中寄存的是“乘法運算的結果”或“除法運算的商”,而寄存器edx中寄存的是“除法運算的余數”,第27至31行用于記錄“寄存運算結果的臨時變量DST對應的寄存器為edx或eax”。

     由于浮點數運算的匯編指令與整數不同,我們需要在圖6.3.5第4行調用EmitX87Assign函數,來對浮點數算術運算進行處理。我們先舉1個例子來講明,對形如“DST: SRC1+SRC2”的2元浮點數運算來講,我們可按以下步驟來生成匯編代碼:

   (1)若SRC1不在x87棧頂寄存器中,則先對x87棧頂寄存器進行必要的回寫,然后把SRC1加載到x87棧頂寄存器中。

   (2)對x87棧頂寄存器與SRC2進行加法運算,結果存于x87棧頂寄存器中。

    按這個思路,我們可為浮點數中間指令“t6: d+e”產生以下匯編代碼:

flds  d     //把浮點數d從內存加載到x87棧頂寄存器

         fadds  e    //完成加法運算后,x87棧頂寄存器即為t6的值

    而對形如“DST:-SRC1”的1元運算來講,我們在上述第(2)步中,只要對x87棧頂寄存器進行1元運算便可,運算后的結果仍存于x87棧頂寄存器中。例如,我們可為“t7: -d”產生以下匯編代碼。

         flds  d     //把浮點數d從內存加載到x87棧頂寄存器

         fchs        //把符號位取反,x87棧頂寄存器即為t7的值

     現在,我們可以來分析1下“用于產生這些浮點運算匯編代碼”的函數EmitX87Assign,如圖6.3.6所示。如果SRC1還未加載到x87棧頂寄存器中,我們就通過第5行進行必要的回寫,然后在第6行把SRC1從內存加載到x87棧頂寄存器中。如果SRC1的值已在x87棧頂寄存器中,此時SRC1必為臨時變量,若SRC1還要在后續的中間指令中被使用,我們需要在第10行把SRC1的值回寫到內存中,由于進行浮點運算后,棧頂寄存器保存的是DST的值,而非SRC1的值。如果操作數SRC2就是SRC1,由于遇到形如第13行的模板“faddl  %2”時,我們要把x87棧頂寄存器與位于內存中的SRC2進行加法運算,而此時SRC2就是SRC1,因此我們也要在第10行把SRC1的值回寫到內存中。第15行根據匯編指令模板,調用PutASMCode函數產生浮點數運算的匯編指令。


圖6.3.6  EmitX87Assign()

        
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 成人春色在线观看免费网站 | 午夜理伦三级播放 | 亚洲韩国日本欧美一区二区三区 | аbt天堂资源在线官网 | 2018年成人精品 | 国产成人女人视频在线观看 | 欧美性色欧美a在线观看 | 亚洲一区 欧美 | 亚洲精品视频在线观看免费 | 亚洲线精品一区二区三区 | 丁香九月婷婷 | 999精品久久久中文字幕蜜桃 | 国产成人精品曰本亚洲 | 欧美一二三区视频 | 午夜性色福利视频 | 色琪琪一本到影院 | 亚洲第一成人在线 | 亚洲成人第一 | 日韩v片| 欧美xxxx做受视频 | 日韩亚洲欧美日本精品va | 亚洲欧美天堂 | 国产亚洲免费观看 | 性欧美18~19sex高清播放 | 亚洲毛片免费视频 | 最近最新中文字幕8 | 欧美在线看欧美视频免费网站 | 久久久久久一级毛片免费野外 | 久久99久久99精品免观看麻豆 | 亚洲欧美日本国产 | 伊人久久久久久久久久 | 日韩有码在线视频 | 国产在线一91区免费国产91 | 最新中文字幕一区二区乱码 | 日欧毛片 | 亚洲成年人免费网站 | 一区二区三区中文国产亚洲 | 一级做a爱片久久毛片 | 91久久精品都在这里 | 成人精品一区二区激情 | 午夜视频在线免费播放 |