天天看點

CSAPP第三章之算術指令

算術操作

一些指令類

每一個指令類都有各種不同大小操作數的變種(除

leaq

外)

指令 效果 描述
leaq S, D D<-&S 加載有效位址
INC D D<-D+1 加一
DEC D D<-D-1 減一
NEG D D<- -D 取負
NOT D D<-~D 取反
ADD S, D D<-D+S 相加
SUB S, D D<-D-S 相減
IMUL S, D D<-D×S 相乘
XOR S, D D<-D^S 異或
OR S, D D<-D|S
AND S, D D<-D&S
SAL k, D D<-D<<k 左移
SHL k, D D<-D<<k 左移,等同于SAL
SAR k, D D<-D>>Ak 算術右移
SHR k, D D<-D>>LK 邏輯右移(logic)
  • ATT格式的代碼,操作數的順序與一般的直覺相反

加載有效位址

leaq

其實是

movq

指令的變形

它根本沒有引用記憶體,而是直接将有效位址寫入目的操作數

目的操作數必須是寄存器

它還可以簡潔地描述普通的算術操作。

例如,當

%rdx

值為x時,

leaq 7(%rdx,%rdx, 4), %rax

是設定寄存器

%rax

的值為5x+7(不了解)

一進制操作與二進制操作

一進制操作:隻有一個操作數,既是源也是目的

二進制操作:第二個操作數既是源也是目的

移位操作

移位量可以是一個立即數,或者放在單位元組寄存器

%cl

中——移位指令隻允許使用該寄存器作為操作數

移位量由

%cl

的低位決定

左移指令有兩個名字:

SAL

SHL

,兩者相同

右移指令:

SAR

(算術移位)與

SHR

(邏輯移位)

移位操作的目的操作數可以是一個寄存器或者是一個記憶體位置

上述的大多數指令既可以用于有符号運算,也可以用于無符号運算

隻有右移才有區分

通常,一個寄存器會存放多個值,還會在寄存器之間傳送程式值

特殊的算術操作

兩個64位的整數相乘需要128位來表示結果

乘除法分為有符号與無符号,例如

imul

idiv

一個特殊的指令:

cqto

:轉換為8字(16位元組)

imul

的兩種形式:

  1. 64位乘64位->64位,同時實作無符号乘法與補碼乘法
  2. 計算兩個64位值的全128位乘積:

    mulq

    imulq

    。要求必須有一個參數在

    %rax

    種,另一個作為源操作數給出,結果放在

    %rdx

    (高64位)與

    %rax

    (低64位)中

    彙編器能通過計算操作數的數目判斷你運作的是哪一條指令

使用

inttype.h

——GCC提供的128位整數支援定義128位數字

除法與取模操作用單操作數除法指令提供。

idivl

将寄存器

%rdx

%rax

中的128數作為被除數,将指令的操作數作為除數給出

商存儲在

%rax

中,餘數存儲在

%rdx

有符号除法:

%rax

全為符号位

無符号除法:

%rax

全為0

繼續閱讀