常见汇编指令和EFLAGS寄存器对应位的含义
IDA的汇编采用的Intel语法
汇编指令的后面通常跟一个操作数,操作数可能是常量,内存变量或者寄存器。
常量:
mov eax, 0x1234
16进制1234就是常量。
IA-32中一般之关注8个32位的通用寄存器,分别是EAX,EBX,ECX,EDX,ESI,EDI,EBP和ESP
栈指针式ESP寄存器,通常指向栈段的顶端,栈在IA-32上是向下增长的,栈的顶端是栈使用地址中的最小值
栈的特点
- 在IA-32平台上,栈向着较小的地址增长
- 栈以LIFO(后进先出)的顺序移去或增加数据
- 局部变量及只存在于函数生命周期的变量随着栈的取消而结束
- 每个函数都会有包含局部变量的栈帧
- 在每个函数的栈帧之前有保存的帧指针,返回地址和例程的参数。
- 栈帧在预处理期间构造,在扫尾例程执行期间取消
预处理执行:
首先把调用帧里下一条指令的地址压入栈,接下来把当前栈的基址(EBP)保存到栈上push操作,
然后把ESP寄存器复制到EBP寄存器里mov操作,最后把ESP寄存器里的值减去一部分,从而为函数里的变量分配空间,当函数被调用时,函数的参数以逆序压入栈(或者是最后的先压入)。预处理对应的汇编指令如下:
push ebp
mov ebp,esp
sub esp, 0x1234
常用指令
mov
作用时把一个特定类型的操作数复制到另一个操作数
and
把操作数与源操作数按位做AND操作,并把结果保存在目标数。
如果两个位都是1则输出1,否则输出0.
not
逐位对单一操作数做NOT操作,将1设为0,反之亦然。
or
逐位对操作数做OR操作,它按位比较两个操作数,当比较的两个
位都为0时它才输出0,否则输出1
xor
逐位比较源操作数与目标操作数,并把结果保存到目标操作数,
如果被比较的两个位不一样才输出1,否则输出0.
test
逐位对第一个和第二个操作数做AND操作,根据结果设置EFLAGS
寄存器中的标志,此指令并不保存操作结果。
cmp
该指令比较两个操作数的大小,用它的目标数减去源操作数,并根据结果设置EFLAGS寄存器的标志。使用方式类似test,主要用于比较操作
lea(取有效地址指令)
该指令计算源操作数指定的地址,并把结果保存在目标操作数中
它用于多个寄存器间做算术运算,并不修改源操作数。
jmp
该指令把执行控制权交给它的操作数。可以执行4中不同类型的跳转
近跳转、短跳转、远跳转和任务切换。
近跳转的目的地址只能在当前代码段里。
短跳转可以跳到与当前地址相距-128到127的地址内
远跳转可以跳到地址空间里任何一个段里,前提是他们与当前代码段同样的特权级
任务切换跳转则可以跳到不同的任务里。
jcc
它是一系列条件跳转命令的统称。具体条件随着使用的指令有所变化,
基本是搭配都是test与cmp指令使用
call
设置栈,使处理器在被调用的函数执行完成后可以恢复执行
ret
它是call指令的搭档。可以从栈里获取保存的元数据,弹出元数据并返回那个地址。
它后面带的立即操作数指定率在执行返回后从栈上弹出多少个字节。
EFLAGS寄存器
它是32位寄存器,包含一组状态,系统标志以及控制状态,每个标志由寄存器里一位代表,
1、状态标志(Status Flags)
EFLAGS寄存器的状态标志(0、2、4、6、7以及11位)指示算术指令(如ADD, SUB, MUL以及DIV指令)的结果,这些状态标志的作用如下:
- CF(bit 0) [Carry flag] 进位标志,若算术操作产生的结果在最高有效位(most-significant bit)发生进位或借位则将其置1,反之清零。这个标志指示无符号整型运算的溢出状态,这个标志同样在多倍精度运算(multiple-precision arithmetic)中使用。
- PF(bit 2) [Parity flag] 奇偶标志,如果结果的最低有效字节(least-significant byte)包含偶数个1位则该位置1,否则清零。
- AF(bit 4) [Adjust flag] 辅助进位标志,如果算术操作在结果的第3位发生进位或借位则将该标志置1,否则清零。这个标志在BCD(binary-code decimal)算术运算中被使用。
- ZF(bit 6) [Zero flag] 零标志,若结果为0则将其置1,反之清零。
- SF(bit 7) [Sign flag] 符号标志,该标志被设置为有符号整型的最高有效位。(0指示结果为正,反之则为负)
- OF(bit 11) [Overflow flag] 溢出标志如果整型结果是较大的正数或较小的负数,并且无法匹配目的操作数时将该位置1,反之清零。这个标志为带符号整型运算指示溢出状态。
2、DF(bit10)标志(DF flag)
方向标志,这个方向标志(位于EFLAGS寄存器的第10位)控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)。设置DF标志使得串指令自动递减(从高地址向低地址方向处理字符串),清除该标志则使得串指令自动递增。STD以及CLD指令分别用于设置以及清除DF标志。
3、系统标志以及IOPL域(System Flags and IOPL Field)
EFLAGS寄存器中的这部分标志用于控制操作系统或是执行操作,它们不允许被应用程序所修改。这些标志的作用如下:
- TF(bit 8) [Trap flag] 陷阱标志,将该位设置为1以允许单步调试模式,清零则禁用该模式。
- IF(bit 9) [Interrupt enable flag]允许中断标志 该标志用于控制处理器对可屏蔽中断请求(maskable interrupt requests)的响应。置1以响应可屏蔽中断,反之则禁止可屏蔽中断。
- IOPL(bits 12 and 13) [I/O privilege level field] I/O特权即标志,指示当前运行任务的I/O特权级(I/O privilege level),正在运行任务的当前特权级(CPL)必须小于或等于I/O特权级才能允许访问I/O地址空间。这个域只能在CPL为0时才能通过POPF以及IRET指令修改。
- NT(bit 14) [Nested task flag] 嵌套任务标志,这个标志控制中断链和被调用任务。若当前任务与前一个执行任务相关则置1,反之则清零。
- RF(bit 16) [Resume flag] 恢复标志,控制处理器对调试异常的响应。
- VM(bit 17) [Virtual-8086 mode flag] 虚拟8086标志, 置1以允许虚拟8086模式,清除则返回保护模式。
- AC(bit 18) [Alignment check flag] 对齐检查标志,该标志以及在CR0寄存器中的AM位置1时将允许内存引用的对齐检查,以上两个标志中至少有一个被清零则禁用对齐检查。
- VIF(bit 19) [Virtual interrupt flag] 虚拟中端标志,该标志是IF标志的虚拟镜像(Virtual image),与VIP标志结合起来使用。使用这个标志以及VIP标志,并设置CR4控制寄存器中的VME标志就可以允许虚拟模式扩展(virtual mode extensions)
- VIP(bit 20) [Virtual interrupt pending flag] 虚拟中断标志,该位置1以指示一个中断正在被挂起,当没有中断挂起时该位清零。【Software sets and clears this flag; the processor only reads it.】与VIF标志结合使用。
- ID(bit 21) [Identification flag] 标识标志,程序能够设置或清除这个标志指示了处理器对CPUID指令的支持。
第22位到31位当前被保留。
参考资料:
IDA权威指南
https://blog.csdn.net/jn1158359135/article/details/7761011