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