深入理解計算機系統(十六):算術和邏輯操作
5 人贊了文章
目錄
1、leal 指令
2、INC、DEC、NEG、NOT 指令
3、ADD、SUB、IMUL、XOR、OR、AND 指令
4、SAL、SHL、SAR、SHR 指令
上一篇博客 我們介紹了幾種數據傳送指令,包括MOV,MOVS,MOVZ,PUSH和POP等,理解起來也不算難。本篇博客我們來接著看彙編語言的算術與邏輯運算指令,算術無非就是加減乘除,而邏輯運算也就是與或非,移位等操作。下面這張圖是彙編裡面的算術和邏輯操作:
上面除了 leal(載入有效地址)指令通常用來執行簡單的算術操作,其餘的指令都是標準的一元或者二元操作,下面我們分別來介紹這幾個指令操作。
正文:
1、leal 指令
leal 指令也稱為載入有效地址(load effective address)指令,它實際上是 movl 指令的變形。它的指令形式是從存儲器讀數據到寄存器,但實際上它根本沒有引用存儲器。
它的第一個操作數看上去是一個存儲器引用,但該指令並不是從指定的位置讀取數據,而是將有效地址寫入到目的操作數,類似於 C 語言的取地址操作符「&」。另外就是作普通的算術運算。
leal 立即數,寄存器
這類指令就是將立即數裝載至寄存器,比如 leal $0x01,%eax 這種情況下 和 movl $0x01,%eax 的效果是等價的
leal 地址,寄存器
leal指令的作用是將地址載入到寄存器,對於leal S,D而言,就是實現了 &S –> D 的功能
leal S, D 結果是&S -> D
movl S,D 結果是S -> D
通用的操作我們就不講了,這裡講一下取地址操作,比如對於leal 4(%edx,%edx,4),%eax這條指令來講,我們假設%edx寄存器的值為x的話,那麼這條指令的作用就是將 4 + x + 4x = 5x + 4賦給%eax寄存器。它和mov指令的區別就在於,假設是movl 4(%edx,%edx,4),%eax這個指令,它的作用是將內存地址為5x+4的內存區域的值賦給%eax寄存器,而leal指令只是將5x+4這個地址賦給目的操作數%eax而已,它並不對存儲器進行引用的值的計算。
為了更好的表示這條指令的效果,這裡簡單的畫個圖來表示這一過程。我們假設下圖是執行指令之前,寄存器和存儲器的狀態。
下面的幾幅圖均引用:http://www.cnblogs.com/zuoxiaolong/p/computer16.html 個人覺得解釋的非常形象。
可以看到,此時在存儲器中,地址為5x+4的區域的值為1000。那麼此時若是進行movl 4(%edx,%edx,4),%eax操作,很顯然,%eax的值應該為1000,也就是下圖。
但是如果進行leal 4(%edx,%edx,4),%eax操作的話,%eax的值就不是1000了,因為leal指令不會去取存儲器當中的值,因此寄存器%eax的值應該是5x+4。
試想一下,倘若在地址為5x+4的位置存儲的是變數i,那麼其實這條指令就相當於&i操作,這也就是C語言當中的&取地址操作的彙編級做法。
此外,它還可以簡單的描述普通的算術操作,比如假如寄存器 %edx 的值為 x,那麼指令 leal 7 (%edx,%edx,4),%eax。 這表示的意思是設置寄存器 %eax 的值為 7+x+4x=5x+7。這裡的leal指令根本與有效地址無關,但是需要注意的是目的操作數必須是寄存器。
2、INC、DEC、NEG、NOT 指令
這四個指令的格式如下:
這四個指令都是一元操作,即它們都只有一個操作數,即是源也是目的。這個操作數可以是寄存器,也可以是存儲器。
比如: incl (%esp) 會使棧頂的 4 位元組元素加 1。可以聯想到 C 語言的自增(++)或者自減(--)
3、ADD、SUB、IMUL、XOR、OR、AND 指令
這一組指令格式如下:
它們都是二元操作,其中第二個操作數即是源又是目的,我們可以聯想到 C 語言的 x += y。
第一個操作數可以是立即數、寄存器或存儲器,第二個操作數可以是寄存器或存儲器位置。不過和 movl 指令一樣,兩個操作數不能同時是存儲器位置。
4、SAL、SHL、SAR、SHR 指令
移位操作,指令格式如下:
第一個操作數是移位量,SAL 和 SHL 都是左移指令,效果是一樣的,移動幾位,右邊補上幾位0;右移指令不同,算術右移 SAR 是補上符號位,即右邊的第一位;邏輯右移 SHR 是補上 0 。
移位的目的操作數可以是一個寄存器或是一個存儲器位置。
推薦閱讀: