汇编
数据宽度
| BYTE | WORD | DWORD |
|---|---|---|
| 8bit | 16bit | 32bit |

汇编指令
| mov | lea | add | sub |
|---|---|---|---|
| 取数据 | 取地址 | 加 | 减 |
| and | or | xor | not |
| & | | | ^ | ! |
进阶
| 指令格式 | 功能 |
|---|---|
| ADC R/M,R/M/IMM | 带进位加法 |
| SBB R/M,R/M/IMM | 带借位减法 |
| XCHG R/M,R/M | 交换数据 |
| MOVS B/W/D :[EDI],:[ESI] | 移动数据(内存-内存)([EDI]/[ESI]根据方向标志DF决定自增/减) |
| STOS B/W/D :[EDI] | 将AL/AX/EAX的值储存到[EDI]指定的内存单元 |
| REP MOVSD/STOSB/… | 按计数寄存器(ECX)中指定的次数重复执行字符串指令 |
| 类型转换 | 功能 |
|---|---|
| MOVSX CX, AL | 符号拓展 |
| MOVZX CX, AL | 无符号拓展 |
内存的读写
MOV DWORD ptr ds:[0x0012FFC4], 0x12345678
汇编、寄存器、堆栈窗口大端序;数据窗口小端序
| 寻址公式 |
|---|
| [立即数] |
| [reg] -> dword ptr ds:[ecx] |
| [reg+立即数] -> dword ptr ds:[ecx+4] |
| [reg+reg*{1, 2, 4, 8}] -> dword ptr ds:[eax+ecx*4] |
| [reg+reg*{1, 2, 4, 8}+立即数] -> dword ptr ds:[eax+ecx*4+4] |
标志寄存器
| 各类标志寄存器 | 值为1的条件 |
|---|---|
| 进位标志CF | 运算结果最高位产生一个进位或借位 |
| 奇偶标志PF | 运算结果中“1”的个数为偶数 |
| 辅助进位标志AF | 在字/字节操作时,低字节/4位向高字节/4位进位或借位 |
| 零标志ZF | 运算结果为0 |
| 符号标志SF | 与运算结果的最高位相同 |
| 溢出标志OF | 有符号数加减运算是否溢出 |

常见汇编及JCC
| 常见汇编 |
|---|
| JMP 寄存器/立即数 修改EIP的值 |
| CALL [A]/寄存器 |
| PUSH [B] |
| MOV EIP,[A]/寄存器 |
| RET -> POP EIP |
| CMP R/M,R/M/IMM |
| TEST R/M,R/M/IMM |
| JCC | 条件 | 标志 |
|---|---|---|
| JE,JZ | 结果为零则跳转 | ZF=1 |
| JNE,JNZ | 结果不为零则跳转 | ZF=0 |
| JS | 结果为负则跳转 | SF=1 |
| JNS | 结果为非负则跳转 | SF=0 |
| JP,JPE | 结果中1的个数为偶数则跳转 | PF=1 |
| JNP,JPO | 结果中1的个数为奇数则跳转 | PF=0 |
| JO | 结果溢出了则跳转 | OF=1 |
| JNO | 结果没有溢出则跳转 | OF=0 |
| JB,JNAE | 小于则跳转(无符号数) | CF=1 |
| JNB,JAE | 大于等于则跳转(无符号数) | CF=0 |
| JBE,JNA | 小于等于则跳转(无符号数) | CF=1 or ZF=1 |
| JNBE,JA | 大于则跳转(无符号数) | CF=0 and ZF=0 |
| JL,JNGE | 小于则跳转(有符号数) | SF!=OF |
| JNL,JGE | 大于等于则跳转(有符号数) | SF=OF |
| JLE,JNG | 小于等于则跳转(有符号数) | ZF=1 or SF!=OF |
| JNLE,JG | 大于则跳转(有符号数) | ZF=0 and SF=OF |
堆栈
push R/M
pop R/M
esp 栈顶 / ebp 栈底
- 无参函数
| 汇编代码 | 功能 |
|---|---|
| call 00E71316 | 调用函数(无参) |
| jmp 00E723D0 | |
| 00E723D0 push ebp 00E723D1 mov ebp,esp 00E723D3 sub esp,0C0h |
提升堆栈 |
| 00E723D9 push ebx 00E723DA push esi 00E723DB push edi |
保留现场 |
| 00E723DC mov edi,ebp 00E723DE xor ecx,ecx 00E723E0 mov eax,0CCCCCCCCh 00E723E5 rep stos dword ptr es:[edi] 00E723E7 mov ecx,0E7E069h 00E723EC call 00E71389 |
为缓冲区填充数据 |
| 00E723F2 pop edi 00E723F3 pop esi 00E723F4 pop ebx |
恢复现场 |
| 00E723F5 add esp,0C0h 00E723FB cmp ebp,esp 00E723FD call 00E7128F |
检查堆栈平衡 |
| 00E72402 mov esp,ebp 00E72404 pop ebp |
降低堆栈 |
| 00E72405 ret | 函数返回 |
- 有参函数(加法)
| 汇编代码 | 功能 |
|---|---|
| 000B1D35 push 2 000B1D37 push 1 |
参数 |
| 000B1D39 call 000B143D | 调用函数 |
| 000B1D3E add esp,8 | 平衡堆栈 |
| 000B143D jmp 000B1CC0 | 中转 |
| 000B1CC0 push ebp 000B1CC1 mov ebp,esp 000B1CC3 sub esp,0C0h |
|
| 000B1CC9 push ebx 000B1CCA push esi 000B1CCB push edi |
|
| 000B1CCC mov edi,ebp 000B1CCE xor ecx,ecx 000B1CD0 mov eax,0CCCCCCCCh 000B1CD5 rep stos dword ptr es:[edi] 000B1CD7 mov ecx,0BE069h 000B1CDC call 000B1389 000B1CE1 nop |
|
| 000B1CE2 mov eax,dword ptr [ebp+8] 000B1CE5 add eax,dword ptr [ebp+0Ch] |
eax中存储的就是返回值 |
| 000B1CE8 pop edi 000B1CE9 pop esi 000B1CEA pop ebx |
|
| 000B1CEB add esp,0C0h 000B1CF1 cmp ebp,esp 000B1CF3 call 000B128F |
|
| 000B1CF8 mov esp,ebp 000B1CFA pop ebp |
|
| 000B1CFB ret | |
- 嵌套函数
| 汇编代码 | 功能 |
|---|---|
| 00761D45 push 3 00761D47 push 2 00761D49 push 1 |
参数 |
| 00761D4B call plus2 (0761442h) | 调用函数 |
| 00761D50 add esp,0Ch | 平衡堆栈 |
| 00761442 jmp plus2 (0762490h) | 中转 |
| 00762490 push ebp 00762491 mov ebp,esp 00762493 sub esp,0CCh 00762499 push ebx 0076249A push esi 0076249B push edi 0076249C lea edi,[ebp-0Ch] 0076249F mov ecx,3 007624A4 mov eax,0CCCCCCCCh 007624A9 rep stos dword ptr es:[edi] 007624AB mov ecx,76E069h 007624B0 call 00761389 007624B5 nop |
|
| 12: int t = plus1(a, b); 007624B6 mov eax,dword ptr [ebp+0Ch] |
eax=2 |
| 007624B9 push eax | 2入栈(参数) |
| 007624BA mov ecx,dword ptr [ebp+8] | ecx=1 |
| 007624BD push ecx | 1入栈(参数) |
| 007624BE call plus1 (076143Dh) | 函数调用 |
| 007624C3 add esp,8 | 平衡堆栈 |
| 007624C6 mov dword ptr [ebp-8],eax | eax是plus1返回结果,ebp-8是局部变量t |
| 13: return plus1(t, c); 007624C9 mov eax,dword ptr [ebp+10h] 007624CC push eax 007624CD mov ecx,dword ptr [ebp-8] 007624D0 push ecx 007624D1 call 0076143D 007624D6 add esp,8 |
同上 |
| 0076143D jmp plus1 (00761CC0h) | |
| 00761CC0 push ebp 00761CC1 mov ebp,esp 00761CC3 sub esp,0C0h 00761CC9 push ebx 00761CCA push esi 00761CCB push edi 00761CCC mov edi,ebp 00761CCE xor ecx,ecx 00761CD0 mov eax,0CCCCCCCCh 00761CD5 rep stos dword ptr es:[edi] 00761CD7 mov ecx,76E069h 00761CDC call 00761389 00761CE1 nop 9: return a + b; 00761CE2 mov eax,dword ptr [ebp+8] 00761CE5 add eax,dword ptr [ebp+0Ch] 00761CE8 pop edi 00761CE9 pop esi 00761CEA pop ebx 00761CEB add esp,0C0h 00761CF1 cmp ebp,esp 00761CF3 call 0076128F 00761CF8 mov esp,ebp 00761CFA pop ebp 00761CFB ret |
plus1(t, c) |
| 007624D9 pop edi 007624DA pop esi 007624DB pop ebx 007624DC add esp,0CCh 007624E2 cmp ebp,esp 007624E4 call 0076128F 007624E9 mov esp,ebp 007624EB pop ebp 007624EC ret |
|
裸函数及其调用约定
|
|
| 调用约定 | 参数压栈顺序 | 平衡堆栈 |
|---|---|---|
| __cdecl | 从右至左入栈 | 调用者清理栈 |
| __stdcall | 从右至左入栈 | 自身清理堆栈->ret 8 |
| __fastcall | ecx/edx传送前两个 剩下:从右至左入栈 |
自身清理堆栈 |
内存图
| if,else,while | 代码区 |
|---|---|
| 参数,局部变量,临时数据 | 堆栈 |
| 动态申请的,大小可变的 可读,可写 |
堆 |
| 可读,可写 | 全局变量区 |
| 只读 | 常量区 |
位运算
| 算数移位 | 指令格式 | 逻辑移位 | 指令格式 |
|---|---|---|---|
| 溢出位进CF | SAL/SAR R/M,CL/I | 溢出位进CF | SHL/SHR R/M,CL/I |
| 算数左移 | SAL(补0) | 逻辑左移 | SHL(补0) |
| 算数右移 | SAR(补符号位) | 逻辑右移 | SHR(补0) |
| 循环移位 | 指令格式 | 带进位循环 | 指令格式 |
| 溢出位进CF | ROL R/M, I ROR R/M, CL |
溢出位进CF | RCL R/M, I RCR R/M, CL |
| 循环左移 | ROL(补溢出位) | 左移 | RCL(补CF位) |
| 循环右移 | ROR(补溢出位) | 右移 | RCR(补CF位) |