上一章我們討論了常見的算術(shù)與邏輯運算指令,其中比較有特點的是leal指令,本章我們再來看幾個比較特殊的操作指令,這些指令可以讓只有32位的寄存器存儲64位的數(shù)據(jù),是不是十分霸氣側(cè)漏呢。
imull、mull指令
這兩個指令一看就是雙胞胎,它們一個負責有符號全64位乘法,一個負責無符號全64位乘法。細心的猿友會發(fā)現(xiàn),imull這個指令好像是負責乘法的指令,而且在之前的乘法并沒有區(qū)分有符號和無符號,現(xiàn)在怎么又成雙胞胎指令了。
我們上一章當中出現(xiàn)的指令是imul指令,當它操作雙字的時候,也就是imull指令。不過不同的是,它的一般形式是imull S D,這里有兩個操作數(shù),它將計算S和D的乘積并截斷為雙字,然后存儲在D當中。由于在截斷時,無符號以及有符號的二進制序列是一樣的,因此此處的乘法指令并不區(qū)分有符號和無符號。
本次我們討論的imull指令,則與上面的普通乘法指令稍有不同,它只有一個操作數(shù),也就是說,它的一般形式為imull S,這點在書中的表格中也能看出來,而另外一個操作數(shù)默認為%eax寄存器。最終的結(jié)果,會將高32位存入%edx寄存器,而低32位存入%eax寄存器。
試想一下,如果我們只取%eax寄存器當中的32位結(jié)果,那其實這里計算的結(jié)果就是S*%eax,此時imull S的作用就與imull S D是一樣的,只是目的操作數(shù)被固定為%eax罷了。
cltd指令
這個指令相對來說就非常簡單了,它就是簡單的將%eax寄存器的值符號擴展32位到%edx寄存器,也就是說,如果%eax寄存器的二進制序列的最高位為0,則cltd指令將把%edx置為32個0,相反,如果%eax寄存器的二進制序列最高位為1,則cltd指令將會自從填充%edx寄存器為32個1。
idivl、divl指令
這兩個指令與前面的imull以及mull類似,它也將計算結(jié)果存放在兩個寄存器當中,其中余數(shù)存放在%edx寄存器,商存放在%eax寄存器。如果各位理解了前面的imull以及mull,那么這里idivl和divl理解起來會非常簡單。
文章小結(jié)
本章介紹了幾個特殊的算術(shù)運算指令,其實這些指令的運算規(guī)則都建立在2.X的基礎之上,2.X當中所介紹的二進制算術(shù)規(guī)則,就是這些指令的執(zhí)行方式規(guī)定。理解這些指令的指令方式,有助于提高我們聯(lián)系程序代碼與匯編代碼之間的對應關系的能力,這是非常有用的。