x86汇编
1.寄存器
-
本环境寄存器大小为2字节 = 1 字型 = 16 bit
-
早期的 x86 CPU 只有8个寄存器,而且每个都有不同的用途,通过DOS环境下我们可以看到有各种寄存器,接下来就一步步的认识它们!
AX --> ah al BX --> bh bl CX --> ch cl DX --> dh dl
-
上面4种通用寄存器,由于兼容早期数据大小,将一个16位大小的寄存器分为俩个8位的 xh属于高地址 xl属于低地址
SP 栈顶指针 BP 基址指针 SI 用于指向源数据的起始地址 DI 用于指向源数据的目标地址 DS 数据段的段地址默认寄存器 ES 附加段地址 SS 栈段的默认段地址存放处 CS 代码段的默认段地址存放处 IP 下一条指令的偏移地址
-
标志寄存器
有的指令会影响标志寄存器 比如: add, sub, mul, div, inc, or, and 大多数为算数和逻辑指令
有的指令没有影响 比如:mov, push, pop 大多数为传送指令
ZF-零标准(Zero Flag) ZF = 1 表示 "结果为0" 1表示"逻辑为真" -----> ZR ZF = 0 表示 "结果为1" 0表示"逻辑为假" -----> NZ PF-奇偶标志(Parity Flag) 当执行的结果的二进制1的个数为偶数 PF的值为1 ---> PE ...... 奇数 PF的值为0 ---> PO SF-符号标志(Sign Flag) 当执行的结果为负 SF=1 ---> NG 当执行的结果为正 SF=0 ---> PL CF-进位标志(Carry Flag) 当计算时对于有效位向更高位借位or进位 CF=1 ---> CY 无 CF=0 ---> NC OF-溢出标志(Overflow Flag) 当进行有符号计算数 有溢出 OF=1 ---> OV 无溢出 OF=0 ---> NV DF-方向标志(Direction Flag) CF与OF的区别: CF对于无符号运算有意义的 进|借位标志 OF对于有符号运算有意义的 溢出标志
2.指令
伪指令
1) .modle
.model flat,stdcall model伪指令告诉汇编程序使用哪一种存储模式: 32位程序总是使用平面(flat)存储模式,它与处理器的保护模式相关联。关键字stdcall在调用程序时告诉汇编器,怎样管理运行时堆栈 .STACK 伪指令,它告诉汇编器应该为程序运行时堆栈保留多少内存字节
2) .STACK
定义一个栈段后面跟数值大小
.stack 1024
3) . ENDS
用于结束块
codesg segment ...... codesg ends
4) . END
用于结束程序
start : ........ end start
5) ALIGN
汇编指令
ALIGN 伪指令将一个变量对齐到字节边界、字边界、双字边界或段落边界
ALIGN 4 ;偏移量按4对齐
1) MOV
将bx寄存器里面的值移到ax寄存器里 mov ax,bx
2) MOVZX 和 MOVSX
MOVZX 指令(进行全零扩展并传送)将源操作数复制到目的操作数,并把目的操作数 0 扩展到 16 位或 32 位。这条指令只用于无符号整数,有三种不同的形式:
movzx 32位通用寄存器, 8位通用寄存器/内存单元 movzx 32位通用寄存器, 16位通用寄存器/内存单元 movzx 16位通用寄存器, 8位通用寄存器/内存单元
MOVSX将用操作数B的符号位扩展填充操作数A的余下空间,如果是负数则符号位为1,如果是正数则和MOVZX功能相同:
MOVSX A,B
3) XCHG
交换两个操作数内容,不能直接交换两个内存操作数
XCHG ax,ax XCHG ax,bx XCHG bx, ax
4) INC 和 DEC
INC(增加)和DEC(减少)指令分别表示寄存器加 1 和减 1:
inc ax dec ax
不支持直接对内存进行操作
5) ADD 和 SUB
操作数相加减
add ax,bx 将ax,bx的寄存器值相加并放入ax寄存器中 sub ax,bx 将ax,bx的寄存器值相减并放入ax寄存器中
6) NEG
计算一个数的二进制数补码
01100100 0x64 按位取反加1 ---> 10011100 9Ch
7) JMP
JMP 指令无条件跳转到目标地址, 并被汇编器转换为偏移量。
JMP 标志符 gool: ... ... jmp gool
8) LOOP
loop指令与cx寄存器绑定,执行多少次由cx值决定
mov cx,10 s: ... ... loop s
首先将cx=cx-1,然后判断是否为0,不为0继续执行
9) PUSH,POP
push时首先减少sp的值,在将值复制到栈中
push ax
pop时首先增加sp的值,指向高地址,在取出值赋值给寄存器中
pop ax
10) PUSHFD,POPFD
PUSHFD 指令把 32 位 EFLAGS 寄存器内容压入堆栈,而 POPFD 指令则把栈顶单元内容弹出到 EFLAGS 寄存器
PUSHFD ;保持标志寄存器 POPFD ;恢复标志寄存器
11) PUSHAD, PUSHA, POPAD, POPA
这里的D可以想成是double,对32位寄存器操作
-
PUSHAD 指令按照 EAX、ECX、EDX、EBX、ESP、EBP、ESI 和 EDI 的顺序(执行 PUSHAD 之前的值),将所有 32 位通用寄存器压入堆栈;POPAD 指令按照相反顺序将同样的寄存器弹出堆栈
-
PUSHA 指令按序(AX、CX、DX、BX、SP、BP、SI 和 DI)将 16 位通用寄存器压入堆栈;POPA 指令按照相反顺序将同样的寄存器弹出堆栈
12) CALL和RET
CALL 指令调用一个过程,会将当前call指令的下一条指令的地址放到堆栈中
ret返回时就是取堆栈中的地址然后改sp的值,指向call的下一条指令
call chunk chunk: ... ... ret
13) AND,OR, XOR, NOT
and ax,bx ; ax和bx的二进制数进行逻辑与运算 or ax,bx ; ax和bx的二进制数进行逻辑或运算 xor ax,bx : 按位异或 not ax ; 按位取反
14) TEST
TEST与AND 指令唯一不同的地方是,TEST 指令不修改目标操作数。TEST 指令允许的操作数组合与 AND 指令相同。在发现操作数中单个位是否置位时,TEST 指令非常有用
; 测试AL寄存器的位0和位3是否为1 TEST al, 00001001b
当所以测试位都为0时,零标志位ZF才为1
15) CMP指令
比较整数: 功能相当于减法指令,只是不保存结果但是会对标志寄存器产生影响
cmp ax,bx
标志位
如果比较的是两个无符号数,则零标志位和进位标志位表示的两个操作数之间的关系如表所示:
CMP结果 | ZF(零标志) | CF(进位标志) |
---|---|---|
ax > bx | 0 | 0 |
ax < bx | 0 | 1 |
ax = bx | 1 | 0 |
如果比较的是两个有符号数,则符号标志位(SF)、零标志位(ZF)和溢出标志位(OF)表示的两个操作数之间的关系如表所示:
CMP结果 | 符号标志位(SF) | 零标志位(ZF) | 溢出标志位(OF) |
---|---|---|---|
ax > bx | 0 | 0 | 0 |
ax < bx | 1 | 0 | 1 |
ax = bx | 0 | 1 | 0 |
一般而言,CMP指令与跳转指令相结合
CMP指令的作用在于比较之后设置标志位,而跳转指令通过判断标志位来进行跳转,达到if语句的效果
16) 条件跳转指令
指令 | 含义 | 测试条件 |
---|---|---|
je/jz | 相等/结果不为0 | ZF = 1 |
jne/jnz | 不等/结果不为0 | ZF = 0 |
js | 结果为负 | SF = 1 |
jns | 结果非负 | SF = 0 |
jo | 结果溢出 | OF = 1 |
jno | 结果未溢出 | OF = 0 |
jp | 奇偶位为1 | PF = 1 |
jnp | 奇偶位为0 | PF = 0 |
jb/jnae/jc | 低于/不高于等于/有借位 | CF = 1 |
jnb/jae/jnc | 不低于/高于等于/无借位 | CF = 0 |
根据无符号数的结果进行转移指令
jb/jnae/jc | 低于则转移 | CF = 1 |
---|---|---|
jnb/jae/jnc | 高于则转移 | CF = 0 |
jna/jbe | 不高于则转移 | CF = 1 or ZF = 1 |
ja/jnbe | 高于则转移 | CF = 0 and ZF = 0 |
j-Jump e-Equal n-Not b-Below a-Above L-less g-Greater s-Sign C-Carry p-Parity o-Overflow z-Zero
17) 移位和循环移位指令
SHR | 右移 | RCR | 带进位的循环右移 |
---|---|---|---|
SHL | 左移 | RCL | 带进位的循环左移 |
SAR | 算数右移 | SHRD | 双精度右移 |
SAL | 算数左移 | SHLD | 双精度左移 |
ROR | 循环右移 | ROL | 循环左移 |
移位
-
逻辑移位:空出来的位用 0 填充;
-
算数移位:空出来的位用原数据的符号位填充;
循环移位
-
以循环方式来移位即为位元循环
-
当多字节整数以四位为单位进行循环移位时,其效果相当于一次向右或向左移动一个十六进制位。例如,将 6A4Bh 反复循环左移四位,最后就会回到初始值
mov ax, 6A4Bh rol ax, 4 ; AX = A4B6h rol ax, 4 ; AX = 4B6Ah rol ax, 4 ; AX = B6A4h rol ax, 4 ; AX = 6A4Bh
18) MUL指令: 无符号乘法
被乘数放在AX里,如果是使用8位,放在al里
mov al,10h mov bl,10h mul bl ; al = al * bl mov ax,10h mov bx,10h mul bx ; ax = ax * bx
-
当 AX 乘以一个 16 位操作数时,乘积存放在 DX 和 AX 寄存器对中。其中,乘积的高 16 位存放在 DX,低 16 位存放在 AX。如果 DX 不等于零,则进位标志位置 1,这就意味着隐含的目的操作数的低半部分容纳不了整个乘积
-
64 位模式下,MUL 指令可以使用 64 位操作数。一个 64 位寄存器或内存操作数与 RAX 相乘,产生的 128 位乘积存放到 RDX:RAX 寄存器中
19) IMUL指令: 有符号乘法
-
与 MUL 指令不同,IMUL 会保留乘 积的符号,实现的方法是,将乘积低半部分的最高位符号扩展到高半部分
20) DIV指令: 无符号除法
被除数、除数、商和余数之间的关系:
被除数 | 除数 | 商 | 余数 |
---|---|---|---|
AL | 8位寄存器 | AL | AH |
AX | 16位寄存器 | AX | DX |
EAX | 32位寄存器 | EAX | EDX |
-
64 位模式下,DIV 指令用 RDX:RAX 作被除数,用 64 位寄存器和内存操作数作除数, 商存放到 RAX,余数存放在 RDX 中
AL中放商 AH中放余数 mov al, 0083h ; 被除数 mov bl, 2 ; 除数 div bl ; AL = 41h, AH = Olh
21) IDICV: 有符号除法
有符号除法几乎与无符号除法相同,只有一个重要的区别:在执行除法之前,必须对被除数进行符号扩展
符号扩展是指将一个数的最高位复制到包含该数的变量或寄存器的所有高位中
符号拓展指令有:CBW,CWD,CDQ,分别对应:字节转字,字转双字,双字转四字
其他
1.跳转距离
1) 俩个段内转移
-
jmp shor 标号
IP = IP + 8位位移 8位位移 = "标号"处的地址 - jmp指令后的第一个字节的地址 8位位移的范围为-128~127 用补码表示;
-
jmp near ptr 标号
IP = IP + 16位位移 16位位移 = "标号"处的地址 - jmp指令后的第一个字节的地址 16位位移的范围为-32769~32767 用补码表示;
2) 远转移: jmp far ptr 标号
远转移jmp far ptr 标号 | 近转移jmp near ptr 标号 |
---|---|
段间转移 | 段内转移 |
far ptr 指明了跳转的目标地址,包含cs:ip | near ptr 指明了相对于当前ip的偏移地址 |
2.转移地址在内存中的jmp指令
jmp word ptr 内存单元地址 | jmp dword ptr 内存单元地址 |
---|---|
段内转移 | 段间转移 |
从内存单元地址处开始存放着一个字,是转移的目的偏移地址 | 从内存单元地址处开始存放着俩个字,高地址处目的段地址,低地址处是转移的目的偏移地址 |
3. jmp bx ;16位寄存器
4. jmp总结
5. offset 操作符
offset 用于取标号的偏移地址
start: mov ax, bx ; “mov ax, bx”的机器码占两个字节 mov si, offset start start是标号 mov di, offset s0 mov ax, cs:[si] mov cs:[di], ax s0: nop ; nop的机器码占一个字节 nop
6.块级转移数据
movsb movsw 的使用与DF标志密切相关
movsb 默认将 ds:si 的一个字节数据移到 es:di中
1) movsb
-
movsb 当DF中值为0 移动后偏移地址加一
-
当DF中值为1 移动后偏移地址减一
2) movsw
-
movsw 当DF中值为0 移动后偏移地址加二
-
当DF中值为1 移动后偏移地址减二
start: mov ax,0f000h mov ds,ax mov si,0ffffh mov ax,data mov es,ax mov di,15 mov cx,16 std ; std 将 DF标志的值改为1(DF标志是位移标志通常于movsb.movsw连用) rep movsb ; rep 和loop一样循环次数跟 cx相关标签:逆向,x86,汇编,mov,地址,指令,寄存器,ax,bx From: https://blog.csdn.net/2301_82108132/article/details/142833717