常用24条指令

  1. NOP:无操作指令,执行时不改变任何状态,常用于占位或调试。
  2. PUSH x:将值x压入栈中,栈指针(ESP)先减去数据大小,然后存储数据。
  3. POP x:将栈顶的数据弹出到x中,栈指针(ESP)递增,指向下一个数据。
  4. CALL x:将下一条指令的地址压入栈中,并将指令指针(EIP)设置为x,跳转到x处执行。
  5. RET:从栈中弹出返回地址到EIP,若为RET x,则ESP增加x字节。
  6. MOV 目的, 源:将源操作数的值复制到目的操作数中。
  7. LEA x1, x2:将x2的地址加载到x1中,常用于获取变量的地址。
  8. ADD x1, x2:将x2的值加到x1中,结果影响标志寄存器(EFLAGS)。
  9. SUB x1, x2:将x2的值从x1中减去,结果同样影响EFLAGS,不能同时使用内存操作数。
  10. JMP x:无条件跳转到地址x,JMP -2表示无限循环。
  11. JCC x:根据条件跳转到x,条件由EFLAGS决定。
  12. CMP x1, x2:比较x1和x2的大小,设置EFLAGS以反映比较结果。
  13. TEST x1, x2:通过计算两个操作数的逻辑与位运算实现比较操作,根据结果设置EFLAGS
  14. AND x1, x2:按位与操作,将结果存储在x1中。
  15. OR x1, x2:按位或操作,将结果存储在x1中。
  16. XOR x1, x2:按位异或操作,常用于清零,XOR EAX, EAX将EAX清零。
  17. NOT x1:按位取反操作,将结果存储在x1中。
  18. SHL x1, x2:逻辑左移操作,将x1左移x2位,右侧补0。
  19. SHR x1, x2:逻辑右移操作,将x1右移x2位,左侧补0。
  20. IMUL/MULIMUL用于有符号数乘法,MUL用于无符号数乘法。
  21. IDIV/DIVDIV用于无符号数除法,IDIV用于有符号数除法,商和余数分别存储在EAX和EDX中。
  22. REP STOS:前缀REP表示重复执行STOS操作,通常用于初始化内存。
  23. REP MOVS:重复执行MOVS操作,通常用于内存拷贝。
  24. LEAVE:用于从子函数返回时清理栈,等价于MOV ESP, EBP; POP EBP

常用寄存器:

  1. EAX (累加寄存器)

    • 用于算术运算和I/O操作的累加器,常用于存储函数返回值。
  2. EBX (基址寄存器)

    • 通常用于存储数据的基地址,常在数组和数据结构的访问中使用。
  3. ECX (计数寄存器)

    • 用于循环计数和字符串操作,特别是在REP指令中。
  4. EDX (数据寄存器)

    • 用于存储乘法和除法运算的高位结果,或作为I/O操作的额外数据寄存器。
  5. ESI (源索引寄存器)

    • 通常用于指向源数据的地址,特别是在字符串操作中。
  6. EDI (目的索引寄存器)

    • 通常用于指向目标数据的地址,特别是在字符串操作中。
  7. EBP (基指针寄存器)

    • 用于指向当前栈帧的基地址,常用于函数调用和局部变量的访问。
  8. ESP (栈指针寄存器)

    • 指向当前栈顶的位置,所有栈操作(如PUSH和POP)都通过此寄存器进行。
  9. EIP (指令指针寄存器)

    • 指向下一条将要执行的指令的地址,自动更新以指向程序的执行流。
  10. EFLAGS (标志寄存器)

-   存储运算结果的状态标志(如零标志、进位标志、溢出标志等),用于控制程序的执行流。

段寄存器

  1. CS (代码段寄存器)

    • 指向当前执行代码的段,包含指令的地址。
  2. DS (数据段寄存器)

    • 指向默认数据段,通常用于访问程序中的全局变量和静态数据。
  3. SS (栈段寄存器)

    • 指向当前栈的段,配合ESP寄存器使用,管理函数调用和局部变量。
  4. ES (附加段寄存器)

    • 用于字符串操作的附加数据段,通常在某些指令中作为目标段。
  5. FS 和 GS (额外段寄存器)

    • 用于存储特定用途的数据段,常用于线程局部存储和系统调用。

enter image description here

eg:

REP STOS 指令用于重复存储操作,通常用于初始化内存。

REP STOS DWORD PTR ES:[EDI] 的含义如下:

  • REP:前缀,表示后续的指令将被重复执行,重复的次数由 ECX 寄存器的值决定。
  • STOS:存储操作指令,用于将 EAX 寄存器的值存储到目标地址。
  • DWORD PTR:指示操作数的大小为双字(4字节)。
  • ES:[EDI]:表示目标地址为段寄存器 ES 指向的内存地址,具体位置由 EDI 寄存器指定。

这条指令的功能是将 EAX 寄存器中的值存储到 ES 段中由 EDI 指向的内存地址,并且这个操作会重复 ECX 次。每次存储后,EDI 会自动增加4(因为是双字存储),以指向下一个存储位置。

假设 EAX 中的值为 0x12345678ECX 的值为 5EDI 指向的地址为 0x1000,执行 REP STOS DWORD PTR ES:[EDI] 后,内存中的内容将变为:

0x1000: 0x12345678
0x1004: 0x12345678
0x1008: 0x12345678
0x100C: 0x12345678
0x1010: 0x12345678

EDI 在每次存储后自动增加4,直到 ECX 计数为0为止。

执行模型

enter image description here

    • 程序的栈是当前进程的内存地址空间中的一块内存区域
    • 栈在内存的位置(起始地址)因操作系统不同而不同
  • 栈帧
    • 栈帧是当前执行的函数(如函数f)使用的那块栈空间程序执行进入f后,ESP和EBP指向的内存地址之间的内存区域被称为f的栈帧
    • 一般也将f的参数传递、部分寄存器暂存、返回地址暂存等占用的内存空间也算作f的栈帧

enter image description here