算術操作
一些指令類
每一個指令類都有各種不同大小操作數的變種(除
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
的兩種形式:
- 64位乘64位->64位,同時實作無符号乘法與補碼乘法
- 計算兩個64位值的全128位乘積:
與mulq
。要求必須有一個參數在imulq
種,另一個作為源操作數給出,結果放在%rax
(高64位)與%rdx
%rax
(低64位)中
彙編器能通過計算操作數的數目判斷你運作的是哪一條指令
使用
inttype.h
——GCC提供的128位整數支援定義128位數字
除法與取模操作用單操作數除法指令提供。
idivl
将寄存器
%rdx
與
%rax
中的128數作為被除數,将指令的操作數作為除數給出
商存儲在
%rax
中,餘數存儲在
%rdx
中
有符号除法:
%rax
全為符号位
無符号除法:
%rax
全為0