前言
在汇编语言中,db(define byte)被称为伪指令,因为它并不是实际的汇编指令,而是一个用于定义数据的指令,用于告诉汇编器如何处理源代码的指令,但它们不直接对应于机器代码的指令。伪指令用于数据定义、内存分配、段定义等目的。
使用伪指令进行数据定义
在汇编中,只有数据内存占用大小.没有数据类型概念.但是在定义的时候,还是会有一些区别.定义大小的如下:
db(Define byte) 1字节 8位(8bit)dw(Define Word) 2字节 16位(16bit)dd(Define Double Word) 4字节 32位(32bit)dq(Define Quad Word) 8字节 64位(64bit)
不同数据类型的定义
第一个表示的变量(常量)名称,第二个表示的数据大小,第三个表示的是值.
字节(Byte)
var1 db 10 ; 定义一个字节,值为 10
var2 db 'A' ; 定义一个字符
字(Word)
var1 dw 1000 ; 定义一个字,值为 1000
双字(Double Word)
var1 dd 1234567890 ; 定义一个双字,值为 1234567890
四字(Quad Word)
var1 dq 9876543210123456789 ; 定义一个四字,值为 9876543210123456789
定义单精度浮点数(float)
floatValue real4 3.14 ; 定义一个单精度浮点数
; 或者使用 dd
floatValue dd 3.14
定义双精度浮点数(double)
doubleValue real8 3.141592653589793 ; 定义一个双精度浮点数
; 或者使用 dq
doubleValue dq 3.141592653589793
定义数组(字节数组),其他数组修改数据大小即可
.data
var1 db 10, 20, 30, 40, 50 ; 定义一个字节数组
定义字符串
var1 db 'hello world', 0 ; 定义一个以零结尾的字符串
位操作
按位与(& and)
规则:对应二进制位都为1时结果为1,否则为0。
示例:
cpp 1 & 1 = 1 // 0b1 & 0b1 = 0b1 1 & 0 = 0 // 0b1 & 0b0 = 0b0 0 & 0 = 0 // 0b0 & 0b0 = 0b0
应用:判断奇偶性、提取特定位
2. 按位或(| or)
规则:对应二进制位只要有一个为1,结果为1。 示例:
```
cpp
1 | 0 = 1 // 0b1 | 0b0 = 0b1
0 | 0 = 0 // 0b0 | 0b0 = 0b0
```
应用:设置特定位、快速合并标志
3. 按位异或(^ xor)
规则:对应二进制位不同时结果为1,相同时为0。 示例:
```
cpp
1 ^ 0 = 1 // 0b1 ^ 0b0 = 0b1
0 ^ 0 = 0 // 0b0 ^ 0b0 = 0b0
```
应用:切换特定位、两数无临时变量交换
- 任何数与自身异或结果为0(a ⊕ a = 0),且两次异或同一数可恢复原值(a ⊕ b ⊕ b = a)
- 无需额外变量即可交换两个数
- a
^b = b^a - (a
^b)^c = a^(b^c) - 0
^b = b - a
^a = 0
4. 按位取反(~ not)
规则:将操作数的每一位取反(0变1,1变0)。
示例:
cpp ~1 = -2 // 0b1 → 0b111111111111111111111111111110(补码表示)
应用:求反码、位掩码操作
5. 左移(<< shl)
规则:将二进制位向左移动指定位数,右侧补0。 示例:
```
cpp
1 << 1 = 2 // 0b1 → 0b10(十进制2)
```
应用:快速乘法(如 n << 1 等价于 n * 2)
6. 右移(>> shr)
规则:将二进制位向右移动指定位数,左侧补符号位(算术右移)或0(逻辑右移)。 示例:
```
cpp
2 >> 1 = 1 // 0b10 → 0b1(十进制1)
```
应用:快速除法(如 n >> 1 等价于 n / 2)
JCC与EFLAG
EFLAG/FFLAG/RFLAG这个寄存器中的值:
主要标志位:
- 零标志 (
ZF):如果运算结果为零,则设置此标志。 - 符号标志 (
SF):如果运算结果为负数,则设置此标志。 - 进位标志 (
CF):在无符号运算中,如果发生进位,则设置此标志。 - 溢出标志 (
OF):如果有符号运算发生溢出,则设置此标志。 - 辅助进位标志 (
AF):用于二进制加法中的低四位进位。
其他标志位:
- 方向标志 (
DF):影响字符串操作的方向。 - 中断标志 (
IF):控制中断的开启和关闭。 - 陷阱标志 (
TF):用于单步调试。 - 系统标志 (
SF):与特权级和系统调用相关。
修改 EFLAGS 的指令
-
CMP destination, source- 功能:比较两个操作数。
- 标志位影响:
- ZF:如果
destination等于source,则设置为 1;否则为 0。 - SF:根据
destination - source的符号更新。 - OF:根据有符号比较的结果更新。
- CF:如果
destination < source,则设置为 1。
- ZF:如果
-
CMPSB(或CMPSW,CMPSD,CMPSQ)- 功能:比较
ESI和EDI指向的字节(或字、双字、四字)。 - 标志位影响:
- ZF:如果指向的字节或字相等,设置为 1;否则为 0。
- SF:根据比较结果更新。
- OF 和 CF:根据无符号比较的结果更新。
- 功能:比较
-
ADD destination, source- 功能:将
source添加到destination。 - 标志位影响:
- ZF:如果相加结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- OF:如果发生溢出,则设置为 1。
- CF:如果发生进位,则设置为 1。
- 功能:将
-
SUB destination, source- 功能:从
destination中减去source。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF、OF、CF:与
CMP指令相同,更新相应标志。
- 功能:从
-
INC destination- 功能:将
destination增加 1。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- OF:如果
destination为最小值,设置为 1;否则为 0。 - CF:始终为 0。
- 功能:将
-
DEC destination- 功能:将
destination减去 1。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- OF:如果
destination为最大值,设置为 1;否则为 0。 - CF:始终为 0。
- 功能:将
-
AND destination, source- 功能:对
destination和source进行按位与运算。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- PF:根据结果的奇偶性更新。
- 功能:对
-
OR destination, source- 功能:对
destination和source进行按位或运算。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- PF:根据结果的奇偶性更新。
- 功能:对
-
XOR destination, source- 功能:对
destination和source进行按位异或运算。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- PF:根据结果的奇偶性更新
- 功能:对
-
MUL/IMUL- 功能:
MUL进行无符号乘法,IMUL进行有符号乘法。两者都将AX(或EAX)与操作数相乘,结果放入DX:AX(或EDX:EAX)。 - 标志位影响:
- CF:如果结果溢出,则设置为 1。
- OF:如果结果溢出,则设置为 1。
- ZF、SF、PF:根据
AX(或EAX)的结果更新。
- 功能:
-
DIV/IDIV- 功能:
DIV进行无符号除法,IDIV进行有符号除法。两者用DX:AX(或EDX:EAX)作为被除数,除以操作数,结果放入AL(或EAX),余数放入AH(或EDX)。 - 标志位影响:
- CF:如果除法结果溢出,则设置为 1。
- ZF:如果余数为 0,设置为 1。
- SF:根据
AL(或EAX)的结果更新。 - OF:不受此指令影响。
- 功能:
-
NEG destination- 功能:取
destination的相反数(即destination = -destination)。 - 标志位影响:
- ZF:如果结果为 0,设置为 1;否则为 0。
- SF:根据结果的符号更新。
- OF:如果
destination为最小值,设置为 1;否则为 0。 - CF:始终为 0。
- 功能:取
JCC指令
条件跳转指令用于根据 EFLAGS 寄存器中的标志决定是否跳转到特定的标签。不同的条件对应不同的跳转指令。
1. 进位标志位(CF - Carry Flag)
含义:用于反映无符号数运算结果是否产生进位或借位。当进行加法运算时,若最高位产生进位;或进行减法运算时,最高位产生借位,则 CF 置为 1,否则置为 0。
对应的跳转指令
- `jc`(Jump if Carry):若 CF = 1 则跳转。
- `jnc`(Jump if No Carry):若 CF = 0 则跳转。
2. 零标志位(ZF - Zero Flag)
含义:反映运算结果是否为 0。若运算结果为 0,则 ZF 置为 1;否则置为 0。
对应的跳转指令
- jz(Jump if Zero):若 ZF = 1 则跳转。
- jnz(Jump if Not Zero):若 ZF = 0 则跳转。
3. 符号标志位(SF - Sign Flag)
含义:反映有符号数运算结果的符号。若运算结果为负数(最高位为 1),则 SF 置为 1;若结果为正数或 0(最高位为 0),则 SF 置为 0。
对应的跳转指令
- js(Jump if Sign):若 SF = 1 则跳转。
- jns(Jump if Not Sign):若 SF = 0 则跳转。
4. 溢出标志位(OF - Overflow Flag)
含义:用于反映有符号数运算结果是否溢出。当有符号数运算结果超出了所能表示的范围时,OF 置为 1;否则置为 0。
对应的跳转指令
- jo(Jump if Overflow):若 OF = 1 则跳转。
- jno(Jump if No Overflow):若 OF = 0 则跳转。
5. 奇偶标志位(PF - Parity Flag)
含义:反映运算结果低 8 位中 1 的个数的奇偶性。若低 8 位中 1 的个数为偶数,则 PF 置为 1;若为奇数,则 PF 置为 0。
对应的跳转指令
- jp(Jump if Parity):若 PF = 1 则跳转。
- jnp(Jump if No Parity):若 PF = 0 则跳转。
方向标志位(DF - Direction Flag)
含义:用于控制串操作指令(如 movs、cmps 等)中地址指针的增减方向。当 DF = 0 时,地址指针自动递增;当 DF = 1 时,地址指针自动递减。
对应的跳转指令:通常没有直接基于 DF 标志位的跳转指令,但可以使用 std(Set Direction Flag,将 DF 置为 1)和 cld(Clear Direction Flag,将 DF 置为 0)指令来设置 DF 的值。
中断允许标志位(IF - Interrupt Enable Flag)
含义:用于控制外部可屏蔽中断的响应。当 IF = 1 时,CPU 可以响应外部可屏蔽中断;当 IF = 0 时,CPU 不响应外部可屏蔽中断。
对应的跳转指令:通常没有直接基于 IF 标志位的跳转指令,但可以使用 sti(Set Interrupt Flag,将 IF 置为 1)和 cli(Clear Interrupt Flag,将 IF 置为 0)指令来设置 IF 的值。
其他跳转指令
-
je(Jump if Equal) :- 当 ZF = 1 时跳转。
- 示例:
cmp eax, ebx je equal_label ; 如果相等则跳转
-
jne(Jump if Not Equal) :- 当 ZF = 0 时跳转。
- 示例:
cmp eax, ebx jne not_equal_label ; 如果不相等则跳转
-
jg(Jump if Greater) :- 当 ZF = 0 且 SF = OF 时跳转。
- 示例:
cmp eax, ebx jg greater_label ; 如果大于则跳转
-
jl(Jump if Less) :- 当 SF ≠ OF 时跳转。
- 示例:
cmp eax, ebx jl less_label ; 如果小于则跳转
-
jge(Jump if Greater or Equal) :- 当 ZF = 0 或 SF = OF 时跳转。
- 示例:
cmp eax, ebx jge greater_equal_label ; 如果大于或等于则跳转
-
jle(Jump if Less or Equal) :- 当 SF ≠ OF 或 ZF = 1 时跳转。
- 例:
cmp eax, ebx jle less_equal_label ; 如果小于或等于则跳转