☰
x86x64汇编基础命令精讲
2026/9/27 15:22:51 网站建设 项目流程

一. 汇编基础

1.1 计算机架构

架构位数指令集特点常见设备
x8632位CISC老架构,兼容性好老电脑
x86-64(AMD64)64位CISC当前PC主流,性能强台式机、笔记本
ARM32位RISC低功耗移动设备
ARM6464位RISC高性能低功耗新型笔记本、平板

32位程序的内存地址都是4个字节,64位程序的内存地址都是8个字节

1.2 汇编基础

1.2.1 CPU(中央处理器)

  • CPU是计算机的“大脑”,负责指挥整个计算机系统的工作。它从内存中读取指令,并根据这些指令进行计算和数据处理。

1.2.2 寄存器(Registers)

  • 寄存器是 CPU 内部的高速存储单元。它用于存放临时的数据和计算的中间结果,具有非常快的访问速度。
  • 寄存器的数量和种类有限,但它们比内存更快,因为它们直接位于CPU 内部。
  • 常见的寄存器有:
    • 通用寄存器(如EAX、EBX)
    • 指针寄存器(如ESP、EBP)
    • 标志寄存器(如EFLAGS)

1.2.3内存(RAM 主存储器)

  • 内存用于存放正在运行的程序的数据和指令。与寄存器相比,内存空间要大得多,但访问速度较慢。
  • CPU 会从内存中读取指令,并在内存中读取或写入数据。
  • 内存通过内存总线与 CPU 和其他硬件组件进行连接。

1.3 寄存器

1.3.1 32位

在32位 x86 架构中,有8个主要通用寄存器:

寄存器名称主要作用PWN/逆向中的用途
EAX累加寄存器存放计算结果、函数返回值保存返回值、系统调用编号
EBX基址寄存器存放基地址、内存地址保存数据地址
ECX计数寄存器循环计数、字符串操作循环次数、rep指令
EDX数据寄存器辅助计算、存放数据乘除法高32位
ESI源变址寄存器源地址指针字符串复制源地址
EDI目的变址寄存器目标地址指针字符串复制目标地址
ESP栈指针寄存器指向当前栈顶栈操作、栈溢出
EBP栈基址寄存器指向当前栈底函数栈帧、调试

1.3.2 标志寄存器

标志位全称说明
CFCarry Flag(进位标志)表示加法或移位操作是否产生进位
ZFZero Flag(零标志)表示运算结果是否为零
SFSign Flag(符号标志)表示运算结果的符号位
OFOverflow Flag(溢出标志)表示加法或减法是否发生了溢出
PFParity Flag(偶校验标志)用于检查结果是否具有偶数个 1
DFDirection Flag(方向标志)用于字符串操作时的方向控制(增量或减量)
AFAuxiliary Carry Flag(辅助进位标志)用于 BCD 运算

1.3.3fs寄存器

作用

  • fs 用来定位当前线程的线程环境块 TEB(Thread Environment Block)

fs:[0]

  • 存储当前线程 TEB 的地址

1.3.4 TEB

  • 线程环境块:是 Windows 为每一个线程创建的数据结构。

  • 在 32 位 Windows 中,TEB 结构大致如下:

    typedefstruct_TEB{NT_TIB NtTib;// +0x0000 TIB用于线程基础信息CLIENT_ID ClientId;// +0x0020 当前线程的 ClientId(包含进程 ID 和线程 ID)PVOID ThreadLocalStoragePointer;// +0x002C 指向线程局部存储(TLS)的指针PVOID ProcessEnvironmentBlock;// +0x0030 指向进程环境块(PEB)的指针ULONG LastErrorValue;// +0x0034 最近错误值// 其他字段...}TEB;

1.3.5 PEB

  • 进程环境块:一个进程是由多个线程构成的

  • 在 32 位 Windows 中,TEB 结构大致如下:

    typedefstruct_PEB{UCHAR BeingDebugged;// +0x002 是否正在调试 这两个都是用来检测的ULONG NtGlobalFlag;// +0x068 Windows调试相关全局标志// ...}PEB;

1.4dbg快捷键

快捷键功能
F9运行程序直到断点(运行)
F7进入函数内部(步入)
F8执行当前指令,不进入函数(步过)
F4运行到光标位置
F12暂停程序
Ctrl + F2重启程序(清除全部断点)
F2设置/取消断点
Ctrl + G跳转到地址
Space修改汇编代码
Enter跳转查看当前光标所在的地址
;添加注释
+ / -进函数/出函数

二. 汇编指令

2.1 数据传输指令

操作符功能示例
mov将数据从源传输到目的位置mov eax, ebx
push将数据压入栈push eax
pop从栈中弹出数据到目的位置pop eax
xchg交换两个操作数的值xchg eax, ebx
lea取地址lea eax, [ebx+4](中括号代表取地址)

2.2 算数运算指令

操作符功能示例
add加法add eax, ebx
sub减法sub eax, ecx
mul无符号乘法mul ecx
imul有符号乘法imul eax, ecx
div无符号除法div ecx
idiv有符号除法idiv ecx
inc自增1inc eax
dec自减1dec eax
指令类型输入输出
mul ecx无符号乘法EAX × ECXEDX:EAX
imul ecx有符号乘法EAX × ECXEDX:EAX
imul eax, ecx有符号乘法EAX × ECXEAX
imul eax, ecx, 10有符号乘法ECX × 10EAX
div ecx无符号除法EDX:EAX ÷ ECXEAX=商,EDX=余数
idiv ecx有符号除法EDX:EAX ÷ ECXEAX=商,EDX=余数

2.3 位运算指令

2.3.1 逻辑运算指令

指令格式功能说明特殊要求
andand target, source按位与:1 & 1 = 1,其余为0,结果保存到target操作数要求同MOV
oror target, source按位或:`11 = 1,1
xorxor target, source按位异或:相同为0,不同为1,结果保存到target同上
notnot target按位非:1 → 0,0 → 1,结果保存到target操作数不能是立即数

注意事项:

  1. 通常使用AND指令对指定位清0
  2. 通常使用OR指令对指定位置1
  3. 通常使用NOT指令将某个数据取反码,再加1就得到补码
  4. 通常使用XOR指令来取反某位
  5. 非运算对标志位不影响,其余指令对标志均会产生影响

2.3.2 移位运算

  • 非循环移位运算
指令格式类型移动方向补位方式标志位影响
SHL(逻辑左移)SHL eax, 1无符号数左移低位补0,最高位移入 CF移位后若 CF ≠ 最高位,则 OF=1,否则 OF=0
SAL(算术左移)SAL eax, 1有符号数左移低位补0,最高位移入 CF与 SHL 相同(操作完全相同)
SHR(逻辑右移)SHR eax, 1无符号数右移高位补0,最低位移入 CF—
SAR(算术右移)SAR eax, 1有符号数右移高位补符号位(原最高位),最低位移入 CF—
  • 循环移位
指令格式名称功能说明
ROLROL eax, 1循环左移(不带进位)最高位移入 CF,同时循环移回最低位
RORROR eax, 1循环右移(不带进位)最低位移入 CF,同时循环移回最高位
RCLRCL eax, 1带进位循环左移最高位移入 CF,CF 原值移入最低位
RCRRCR eax, 1带进位循环右移最低位移入 CF,CF 原值移入最高位

2.4 逻辑比较指令

  • cmp

    cmp eax, ebx # eax - ebx
  • test

    test eax, ebx # eax & ebx 按位与

都是不保存结果,只根据结果修改标志寄存器中的标志位。

2.5 控制转移指令

操作符功能示例
jmp无条件跳转jmp 0x00401000
call调用子程序call 0x00401000
ret返回到调用点ret
je / jz如果相等(ZF 置位)跳转je 0x00401020
jne / jnz如果不等(ZF 未置位)跳转jne 0x00401020
jg如果大于跳转jg 0x00401020
jl如果小于跳转jl 0x00401020
jge如果大于等于跳转jge 0x00401020
jle如果小于等于跳转jle 0x00401020
loop循环跳转loop 0x00401020
int调用中断int 0x80
iret从中断返回iret

巧计跳转:zero,equal,not,great,less

2.6 栈操作指令

指令功能描述栈指针变化(ESP)
PUSH将寄存器值、立即数或内存操作数压入栈顶。例如:PUSH EAX、PUSH 5ESP -= 4
POP将栈顶值弹出并存入寄存器或内存操作数。例如:POP EAXESP += 4
PUSHAD按顺序将通用寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI的值压入栈ESP -= 32
POPAD按顺序从栈中弹出值,恢复通用寄存器:EDI、ESI、EBP、ESP(跳过)、EBX、EDX、ECX、EAXESP += 32
PUSHFD将 32 位标志寄存器EFLAGS压入栈ESP -= 4
POPFD从栈中弹出值并恢复到 32 位标志寄存器EFLAGSESP += 4
CALL调用子程序,将当前指令的返回地址压入栈顶,然后跳转到目标地址ESP -= 4
RET从栈中弹出返回地址,并跳转到该地址ESP += 4
ENTER设置栈帧:将当前EBP压入栈,然后设置新的EBP,并为局部变量分配空间。ESP -= 局部变量大小
LEAVE恢复栈帧:将EBP的值恢复到ESP,然后弹出原来的EBP。mov esp, ebp; pop ebpESP += 局部变量大小
INT imm8软中断:将标志寄存器、代码段(CS)和指令指针(EIP)压入栈,然后跳转到中断向量表中的处理程序地址。ESP -= 12
IRET中断返回:从栈中弹出标志寄存器、代码段(CS)、指令指针(EIP),恢复中断前状态。ESP += 12

2.7 字符串操作指令

字符串指令的一个共同特点:

通常不需要把源地址、目标地址直接写出来,而是默认使用ESI、EDI。

32 位模式下:

ESI → 源字符串 EDI → 目标字符串 ECX → 重复次数
核心指令功能主要作用
MOVSB/MOVSW/MOVSD字符串传送内存 → 内存
CMPSB/CMPSW/CMPSD字符串比较比较两段内存
SCASB/SCASW/SCASD字符串扫描EAX 与内存比较
LODSB/LODSW/LODSD加载字符串内存 → EAX
STOSB/STOSW/STOSD存储字符串EAX → 内存
B = Byte 1字节 W = Word 2字节 D = Double Word 4字节

这些命令常也与rep(重复)搭配使用

2.8 浮点运算指令

FPU 是硬件单元 → x87 是传统浮点指令集 → SSE 是基于 XMM 寄存器的 SIMD 浮点指令集。

1. FPU

  • FPU:浮点运算单元,专门处理浮点数运算。
  • 主要功能:加、减、乘、除、开方、三角函数等。
  • 传统 x86 中 FPU 曾是独立协处理器,80486 起集成到 CPU 内部。
  • 核心寄存器:
    • ST0~ST7:8 个80 位浮点寄存器,以栈结构组织。
    • 状态寄存器:记录 FPU 状态和 C0~C3 标志。
    • 控制寄存器:控制精度、舍入方式等。

2. x87

  • x87:早期 x86 的浮点指令集,主要操作ST0~ST7。
  • 采用浮点寄存器栈。
  • 常见指令:
    • FLD/FST:加载 / 存储
    • FADD/FSUB:加 / 减
    • FMUL/FDIV:乘 / 除
    • FCOM/FUCOM:比较
  • 最大特点:支持80 位扩展精度。

3. SSE

  • **SSE: **Streaming SIMD Extensions,SIMD 扩展指令集。
  • 使用XMM 128 位寄存器。
  • 可以同时处理多个浮点数:
    • PS:Packed Single,多个32 位单精度
    • SD:Scalar Double,单个64 位双精度
  • 相比 x87:
    • 不采用寄存器栈
    • 可以并行处理多个数据
    • 更适合多媒体、游戏、音视频和高性能计算。

三. 函数

3.1 嵌套栈结构

空函数汇编

; 函数头 push ebp ; 保存调用者函数的 ebp mov ebp esp ; 设置当前栈帧基值 ; 执行完上面两行时,ebp+4是返回地址,ebp+8是第一个参数,ebp-xxx都是局部数据 ; 返回值保存在eax中 ; 函数尾 leave ; mov esp, ebp; pop ebp ret

空函数嵌套

push ebp mov ebp esp push xxx ; 参数入栈 call xxx ; 跳转到函数,并把下一条指令的地址压入栈中 leave ret ; 会回到执行call时保存的下一条语句的地址

栈结构

Address Data 描述 Ox0018FF00 [局部变量2] ← EBP - 8 低地址(栈顶方向) Ox0018FF04 [局部变量1] ← EBP - 4 Ox0018FF08 [保存的EBP] ← EBP(当前栈帧基址) Ox0018FF0C [返回地址] ← EBP + 4 Ox0018FF10 [参数1 (a)] ← EBP + 8 Ox0018FF14 [参数2 (b)] ← EBP + 0xC 高地址(栈底方向)

3.2 调用约定

cdecl(C调用约定)

push x push x call func add esp, 8 ; 平衡堆栈(外平栈),8对应两个参数 func: push ebp mov ebp esp ... leave ret

stacall(标准调用约定)

push x push x call func func: push ebp mov ebp esp ... leave retn 8 ; 平衡堆栈(内平栈),8对应两个参数

fastcall

mov ecx, x ; 前两个参数放在ecx和edx,后面的依次入栈 mov edx, x push x call func func: push ebp mov ebp esp ... leave retn 4 ; 平衡堆栈(内平栈),4对应那一个push的参数

thiscall(C++成员函数调用)

mov ecx, obj_ptr ; this指针存入ecx push x push x call func add esp, 8 ; 平衡堆栈(外平栈),8对应两个参数 func: push ebp mov ebp esp ... leave ret ; 可以是retn 8,可内可外

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询