上一篇博客 咱們介紹了幾種數據傳送指令,包括MOV,MOVS,MOVZ,PUSH和POP等,理解起來也不算難。本篇博客咱們來接着看彙編語言的算術與邏輯運算指令,算術無非就是加減乘除,而邏輯運算也就是與或非,移位等操做。下面這張圖是彙編裏面的算術和邏輯操做:html
上面除了 leal(加載有效地址)指令一般用來執行簡單的算術操做,其他的指令都是標準的一元或者二元操做,下面咱們分別來介紹這幾個指令操做。htm
leal 指令也稱爲加載有效地址(load effective address)指令,它其實是 movl 指令的變形。它的指令形式是從存儲器讀數據到寄存器,但實際上它根本沒有引用存儲器。blog
它的第一個操做數看上去是一個存儲器引用,但該指令並非從指定的位置讀取數據,而是將有效地址寫入到目的操做數,相似於 C 語言的取地址操做符「&」。另外就是做普通的算術運算。內存
leal 當即數,寄存器get
這類指令就是將當即數裝載至寄存器,好比 leal $0x01,%eax 這種狀況下 和 movl $0x01,%eax 的效果是等價的博客
leal 地址,寄存器變量
leal指令的做用是將地址加載到寄存器,對於leal S,D而言,就是實現了 &S –> D 的功能引用
leal S, D 結果是&S -> Dim
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指令根本與有效地址無關,可是須要注意的是目的操做數必須是寄存器。
這四個指令的格式以下:
這四個指令都是一元操做,即它們都只有一個操做數,便是源也是目的。這個操做數能夠是寄存器,也能夠是存儲器。
好比: incl (%esp) 會使棧頂的 4 字節元素加 1。能夠聯想到 C 語言的自增(++)或者自減(--)
這一組指令格式以下:
它們都是二元操做,其中第二個操做數便是源又是目的,咱們能夠聯想到 C 語言的 x += y。
第一個操做數能夠是當即數、寄存器或存儲器,第二個操做數能夠是寄存器或存儲器位置。不過和 movl 指令同樣,兩個操做數不能同時是存儲器位置。
移位操做,指令格式以下:
第一個操做數是移位量,SAL 和 SHL 都是左移指令,效果是同樣的,移動幾位,右邊補上幾位0;右移指令不一樣,算術右移 SAR 是補上符號位,即右邊的第一位;邏輯右移 SHR 是補上 0 。
移位的目的操做數能夠是一個寄存器或是一個存儲器位置。