程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 計算機系統原理(十七) 特殊的算術操作指令詳解

計算機系統原理(十七) 特殊的算術操作指令詳解

編輯:匯編語言

引言

上一章我們討論了常見的算術與邏輯運算指令,其中比較有特點的是leal指令,本章我們再來看幾個比較特殊的操作指令,這些指令可以讓只有32位的寄存器存儲64位的數據,是不是十分霸氣側漏呢。

初識

我們先來看看這些指令的大致介紹,如果各位看過上一章的話,會發現這裡的指令有的會有些眼熟,但是它們的作用卻截然不同。以下是書中的一張概圖。

第一個指令有些眼熟吧,它就是我們上一章當中的imul乘法指令的雙字形式。不過可以看出,這裡的imull指令已經完全變了味道,它將結果存入兩個寄存器。接下來,我們來仔細看看這些指令。

imull、mull指令

這兩個指令一看就是雙胞胎,它們一個負責有符號全64位乘法,一個負責無符號全64位乘法。細心的猿友會發現,imull這個指令好像是負責乘法的指令,而且在之前的乘法並沒有區分有符號和無符號,現在怎麼又成雙胞胎指令了。

我們上一章當中出現的指令是imul指令,當它操作雙字的時候,也就是imull指令。不過不同的是,它的一般形式是imull S D,這裡有兩個操作數,它將計算S和D的乘積並截斷為雙字,然後存儲在D當中。由於在截斷時,無符號以及有符號的二進制序列是一樣的,因此此處的乘法指令並不區分有符號和無符號。

本次我們討論的imull指令,則與上面的普通乘法指令稍有不同,它只有一個操作數,也就是說,它的一般形式為imull S,這點在書中的表格中也能看出來,而另外一個操作數默認為%eax寄存器。最終的結果,會將高32位存入%edx寄存器,而低32位存入%eax寄存器。

試想一下,如果我們只取%eax寄存器當中的32位結果,那其實這裡計算的結果就是S*%eax,此時imull S的作用就與imull S D是一樣的,只是目的操作數被固定為%eax罷了。

接下來我們看一個簡單的示例,我們去看下指令imull $0x3的結果,我們假設此時%eax寄存器的值為0x82345600。也就是我們需要計算0x3*0x82345600的值,這裡LZ直接給出兩者相乘的16進制表示,各位有興趣的可以私下乘一下,為0xFFFF FFFE 869D 0200。這個結果為64位的,因此我們寄存器的前後狀態如下所示。

可以看到,%eax保存著低32位的結果,單說這32位的話,它的有符號數值為-2036530688,正是我們直接計算0x3*0x82345600的32位截斷後的有符號值,顯然這個結果溢出了。如果組合上高32位,則結果為-6331497984,將它加上或者取模4294967296(2的32次方)將得到我們32位的結果。這裡的有符號乘法采取的是先符號擴展被乘數,然後兩者相乘,將結果再截斷為64位所得。

對於mull的單操作數指令來講,就比較簡單了,它采用的是無符號乘法,因此就和我們平時的十進制乘法運算類似,只是同樣的,它也會將結果的高32位存入%edx,將低32位存入%eax。

查看本欄目

cltd指令

這個指令相對來說就非常簡單了,它就是簡單的將%eax寄存器的值符號擴展32位到%edx寄存器,也就是說,如果%eax寄存器的二進制序列的最高位為0,則cltd指令將把%edx置為32個0,相反,如果%eax寄存器的二進制序列最高位為1,則cltd指令將會自從填充%edx寄存器為32個1。

idivl、divl指令

這兩個指令與前面的imull以及mull類似,它也將計算結果存放在兩個寄存器當中,其中余數存放在%edx寄存器,商存放在%eax寄存器。如果各位理解了前面的imull以及mull,那麼這裡idivl和divl理解起來會非常簡單。

這裡LZ舉一個簡單的例子,考慮指令idivl $0x3的結果,我們假設此時%eax寄存器的值為0x82345600。也就是我們需要計算0x82345600/0x3的值,這裡LZ直接給出兩者相除的16進制表示,各位有興趣的也可以私下除一下,商為0xD6117200,余數為0x0。因此我們寄存器的前後狀態如下所示。

可以看到,在idivl這個指令執行的過程中,其實對被除數進行了符號擴展,類似於cltd指令,或者有時也會將%eax移動到%edx,然後對%edx進行算術右移31位的運算。這兩種方式的結果是一樣的,都是將%eax符號擴展32位並存儲在%edx當中。

文章小結

本章介紹了幾個特殊的算術運算指令,其實這些指令的運算規則都建立在2.X的基礎之上,2.X當中所介紹的二進制算術規則,就是這些指令的執行方式規定。理解這些指令的指令方式,有助於提高我們聯系程序代碼與匯編代碼之間的對應關系的能力,這是非常有用的。

下一章我們將進入控制結構部分,其中用到了另外一種寄存器,名叫條件寄存器。這在之前我們是提到過這個名字的,到時我們一起來看下,條件寄存器如何控制程序的執行流程。

作者:zuoxiaolong(左潇龍)

出處:博客園左潇龍的技術博客--http://www.cnblogs.com/zuoxiaolong

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved