Assembly

Assembly

Posted by Deetch on July 4, 2017

Intel用术语“字(word)”表示16位数据类型。称32位数为“双字”

C声明       Intel数据类型      汇编代码后缀            大小(字节)
char            字节              b                    1
short           字                w                    2
int             双字              l                    4
long            四字              q                    8
char*           四字              q                    8
float           单精度            s                    4
double          双精度            l                    8
-----------------------------------------------------------------------------------------------
简单数据传送指令

指令                                  效果                              描述
(源操作数指定的值是一个立即数、存储在寄存器中或者内存中,目的操作数指定一个位置,要么是寄存器,要么是内存地址。
x86-64加了一条限制,传送指令的两个操作数不能都指向内存位置)

MOV S, D                             D <-- S                            传送
movb                                                                   传送字节
movw                                                                   传送字
movl                                                                   传送双字
movq      (只能以表示为32位补码数字的立即数作为源操作数)                      传送四字
movabsq   I, R(只能用寄存器作目标)       R <-- I                          传送绝对的四字


-----------------------------------------------------------------------------------------------
零扩展数据传送指令
(以寄存器或内存地址作为源,以寄存器作为目的)

指令                                  效果                              描述

MOVZ S, R                            R <-- 零扩展(S)                   以零扩展进行传送
movzbw                                                                 零扩展的字节传送到字
movzbl                                                                 零扩展的字节传送到双字
movzwl                                                                 零扩展的字传送到双字
movzbq                                                                 零扩展的字节传送到四字
movzwq                                                                 零扩展的字传送到四字


-----------------------------------------------------------------------------------------------
符号扩展数据传送指令
(以寄存器或内存地址作为源,以寄存器作为目的,cltq指令只能作用于寄存器%eax和%rax)

指令                                  效果                              描述

MOVS S, R                            R <-- 符号扩展(S)                  以符号扩展进行传送
movsbw                                                                 符号扩展的字节传送到字
movsbl                                                                 符号扩展的字节传送到双字
movswl                                                                 符号扩展的字传送到双字
movsbq                                                                 符号扩展的字节传送到四字
movswq                                                                 符号扩展的字传送到四字
movslq                                                                 符号扩展的双字传送到四字
cltq                                 %rax <-- 符号扩展(%eax)            把%eax符号扩展到%rax


-----------------------------------------------------------------------------------------------
入栈和出栈指令
(以寄存器或内存地址作为源,以寄存器作为目的,cltq指令只能作用于寄存器%eax和%rax)

指令                                  效果                              描述

pushq  S                                                               将四字压入栈
popq   D                                                               将四字弹出栈


-----------------------------------------------------------------------------------------------
算术和逻辑操作

指令                                  效果                              描述

leaq  S,D                            D <-- &S                          加载有效地址

INC   D                              D <-- D+1                         加1
DEC   D                              D <-- D-1                         减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>>(A)k                     算术右移
SHR   k,D                            D <-- D>>(L)k                     逻辑右移


-----------------------------------------------------------------------------------------------
特殊的算术操作

指令                  效果                                        描述

imulq  S            R[%rdx]:R[%rax] <-- S*R[%rax]                有符号全乘法
mulq   S            R[%rdx]:R[%rax] <-- S*R[%rax]                无符号全乘法

clto                R[%rdx]:R[%rax] <-- 符号扩展(R[%rax])        转换为八字

idivq  S            R[%rdx] <-- R[%rdx]: R[%rax] mod S           有符号除法
                    R[%rdx] <-- R[%rdx]: R[%rax] / S

divq   S            R[%rdx] <-- R[%rdx]: R[%rax] mod S           无符号除法
                    R[%rdx] <-- R[%rdx]: R[%rax] / S

-----------------------------------------------------------------------------------------------
条件码

CF:进位标志。最近的操作使最高位产生了进位。可用来检查无符号操作的溢出  
ZF:零标志。最近的操作得出的结果为0  
SF:符号标志。最近的操作得到的结果为负数  
OF:溢出标志。最近的操作导致一个补码溢出————正溢出和负溢出


-----------------------------------------------------------------------------------------------
比较和测试指令,这些指令不修改任何寄存器的值,只设置条件码

指令                  基于                                        描述

CMP  S1,S2           S2 - S1                                     比较

cmpb                                                             比较字节
cmpw                                                             比较字
cmpl                                                             比较双字
cmpq                                                             比较四字

TEST S1,S2           S1 & S2                                     测试

testb                                                            测试字节
testw                                                            测试字
testl                                                            测试双字
testq                                                            测试四字


-----------------------------------------------------------------------------------------------
SET指令。每条指令根据条件码的某种组合,将一个字节设置为0或者1

指令                同义名                 效果                     设置条件

sete  D            setz                  D <-- ZF                相等/零
setne D            setnz                 D <-- ~ZF               不等/非零

sets  D                                  D <-- SF                负数
setns D                                  D <-- ~SF               非负数

setg  D            setnle                D <-- ~(SF^OF) & ~ZF    大于(有符号>)
setge D            setnl                 D <-- ~(SF^OF)          大于等于(有符号>=)
setl  D            setnge                D <-- SF^OF             小于(有符号<)
setle D            setng                 D <-- (SF^OF) | ZF      小与等于(有符号<=)

seta  D            setnbe                D <-- ~CF & ~ZF         超过(无符号>)
setae D            setnb                 D <-- ~CF               超过或相等(无符号>=)
setb  D            setnae                D <-- CF                低于(无符号<)
setbe D            setna                 D <-- CF | ZF           低于或相等(无符号<=)


-----------------------------------------------------------------------------------------------
jump指令。当跳转条件满足时,这些指令会跳转到一条带标号的目的地。

指令                同义名                 跳转条件                     描述

jmp Label                                1                           直接跳转
jmp *Operand                             1                           间接跳转

je Label           jz                    ZF                          相等/零
jne Label          jnz                   ~ZF                         不相等/非零

js Label                                 SF                          负数
jns Label                                ~SF                         非负数

jg Label           jnle                  ~(SF^OF) & ~ZF              大于(有符号>)
jge Label          jnl                   ~(SF^OF)                    大于或等于(有符号>=)
jl Label           jnge                  SF^OF                       小于(有符号<)
jle Label          jng                   (SF^OF) | ZF                小于或等于(有符号<=)

ja Label           jnbe                  ~CF & ~ZF                   超过(无符号>)
jae Label          jnb                   ~CF                         超过或相等(无符号>=)
jb Label           jnae                  CF                          低于于(无符号<)
jbe Label          jna                   CF | ZF                     低于或相等(无符号<=)


-----------------------------------------------------------------------------------------------
条件传送指令。当传送条件满足时,指令把源值S复制到目的R。
源地址可以时寄存器或者内存地址,目的地址只能是寄存器
源和目的的值可以是16位、32位或64位。不支持单字节的条件传送

指令                同义名                 传送条件                     描述

cmove S,R          cmovz                 ZF                          相等/零
cmovne S,R         cmovnz                ~ZF                         不相等/非零

cmovs S,R                                SF                          负数
cmovns S,R                               ~SF                         非负数

cmovg S,R          cmovnle               ~(SF^OF)&~ZF                大于(有符号>)
cmovge S,R         cmovnl                ~(SF^OF)                    大于或等于(有符号>=)
cmovl S,R          cmovnge               SF^OF                       小于(有符号<)
cmovle S,R         cmovng                (SF^OF)|ZF                  小于或等于(有符号<=)

cmova S,R          cmovnbe               ~CF & ~ZF                   超过(无符号>)
cmovae S,R         cmovnb                ~CF                         超过或相等(无符号>=)
cmovb S,R          cmovnae               CF                          低于(无符号<)
cmovbe S,R         cmovna                CF | ZF                     低于或相等(无符号<=)


-----------------------------------------------------------------------------------------------
转移控制

指令                        描述

call Label                  过程调用
call *Operand               过程调用
ret                         从过程调用中返回

寄存器使用规则

寄存器

63                 31                 15           7            0

rax               eax                 ax           al                   返回值
rbx               ebx                 bx           bl                   被调用者保存
rcx               ecx                 cx           cl                   第4个参数
rdx               edx                 dx           dl                   第3个参数
rsi               esi                 si           sil                  第2个参数
rdi               edi                 di           dil                  第1个参数
rbp               ebp                 bp           bpl                  被调用者保存
rsp               esp                 sp           spl                  栈指针
r8                r8d                 r8w          r8b                  第5个参数
r9                r9d                 r9w          r9b                  第6个参数
r10               r10d                r10w         r10b                 调用者保存
r11               r11d                r11w         r11b                 调用者保存
r12               r12d                r12w         r12b                 被调用者保存
r13               r13d                r13w         r13b                 被调用者保存
r14               r14d                r14w         r14b                 被调用者保存
r15               r15d                r15w         r15b                 被调用者保存
x86-64中,可以通过寄存器最多传递6个整型(例如整数和指针)参数。寄存器的使用是有特殊
顺序的,寄存器使用的名字取决于要传递的数据类型的大小。如果超出6个整型参数,超出的部
分通过栈传递

操作数大小                               参数数量
                1       2       3       4       5       6

64             %rdi     %rsi    %rdx    %rcx    %r8     %r9
32             %edi     %esi    %edx    %ecx    %r8d    %r9d
16             %di      %si     %dx     %cx     %r8w    %r9w
8              %dil     %sil    %dl     %cl     %r8b    %r9b

确定分支预测错误的处罚

Tavg(p) = (1 - p)Tok + p(Tok + Tmp) = Tok + pTmp

Tran = Tavg(0.5) = Tok + 0.5Tmp Tmp = 2(Tran - Tok)

Tok:预测准确,执行代码的时间 Tmp:预测错误的处罚时间 Tavg:执行代码的平均时间 Tran:随机情况下,每次调用需要的周期 Tran = Tavg(0.5)

附录

2.3.7节内容;被除数是负数的话,必须加上偏移量 2^k - 1