# 汇编 ## X86-64,x64,amd64 ### 寄存器 #### 通用寄存器 通用寄存器有64 32 16 8(低) 8(高)几种 - rax/eax/ax/al/ah: 累加器 函数调用的返回值一般也在这里 - rbx/ebx/bx/bl/bh: 存放内存寻址时的基地址 - rcx/ecx/cx/cl/ch: 计数器 例如for循环 - rdx/edx/dx/dl/dh: 存放整除的余数 函数传参的第三个参数 - rsi/esi/si/sil: 源索引寄存器,经常用于字符串操作 - rdi/edi/di/dil: 目标索引寄存器,经常用于字符串操作 - rbp/ebp/bp/bpl: 栈基指针 访问栈帧数据 - rsp/esp/sp/spl: 栈指针 指向栈顶 - r[8-15]: 通用寄存器 #### 标志位寄存器 标志位寄存器存储某些指令计算的结果 反应计算的状态 x86的标志位寄存器为EFLAGS(32位)和RFLAGS(64位) 标志位分为*状态标志位*和*控制标志位* ##### 状态标志位 1. ZF 零标志 若运算的结果为0 则ZF=1 否则为0 经常用于比较指令如cmp 跳转指令如JE 2. SF 符号标志 若运算结果为负(最高位为1) 则SF=1 经常和OF一起可以判断结果的符号 3. CF 进位标志 若`无符号`的运算结果产生了进位 则CF=1 经常与CMP一起用 4. OF 溢出标志 若`有符号`的运算结果超出了范围 则OF=1 经常用于有符号数的比较和算数 5. AF 辅助进位标志 若运算结果的`低4位`向`高4位`产生了进位或错位 则AF=1 主要用于BCD算数运算 6. PF 奇偶校验标志 若运算结果的低8位的1的个数为偶数 则PF=1 主要用于数据通信中的错误校验 ##### 控制标志位 1. DF 方向标志 控制字符串指令的读写方向 若递增(向前)则DF=0 2. IF 中断标志 控制CPU是否响应可屏蔽硬件中断 若中断禁用则IF=0 3. TF 陷阱标志 若CPU在每条指令后都会产生一个单步中断则TF=1 ### 指令 #### 比较操作 这部分为数学运算指令 ##### test 对两操作数做按位AND运算 *仅修改标志位(flags) 不会回写结果到寄存器* ```asm test dest,source ``` ZF: 若AND结果为0则ZF=1 SF: 最高位为1 则SF=1 CF: 0 OF: 0 *test是判断寄存器是否为0最快的方法* 因为将寄存器和自己取AND 若为0则ZF=1 ```asm test eax,eax ``` ##### cmp 减法操作 并把结果写入标志位 和test一样也丢弃结果 ```asm cmp dest,source ``` 计算 $dset - source$ - dest > source CF=0,ZF=0 - dest < source CF=1 发生了借位 - dest = source ZF=1,CF=0 #### 条件转移 根据CPU标志位跳转 跳转取决于EFLAGS/RFLAGS中的ZF,SF,OF等标志位 - `jle`: 代表<= 条件为ZF=1 or SF != OF #### 算数运算 ##### xor 异或运算 将dest和source的异或结果赋值到dest ```asm xor dest,source ``` ZF: 若XOR结果为0则ZF=1 SF: 最高位为1 则SF=1 CF: 0 OF: 0