常见汇编指令和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

posted @ 2020-12-16 15:46  公众号python学习开发  阅读(750)  评论(0编辑  收藏  举报