1.算术运算
+、-、*、/、%、++、--
#include <stdio.h>
void main()
{
int x = 1;
int y = 2;
int z = 3;
x++;
y--;
z /= x; // z = z/x;
z %= x; // z = z%x;
printf("%d, %d, %d/r/n", x, y, z);
x = x + y;
z -= x; // z = z-x;
printf("%d, %d, %d/r/n", x, y, z);
}
汇编指令集
mov/lea: 赋值/取地址
add: 加法指令
sub: 减法指令 subtract
div/idiv: 除法指令 divide
mul/imul: 乘法指令 multiplication
通用寄存器(用C语言来解释,可以把寄存器当做变量看待)
EAX:累加器(accumulator),是很多加法乘法指令的缺省寄存器
EBX:基地址(base),在内存寻址时存放基地址
ECX:计数器(counter),重复(REP)前缀指令和LOOP指令的内定计数器
EDX:用来存放整数除法产生的余数
ESI/EDI:源/目标索引寄存器(source/destination index)
在很多字符串操作指令中DS:ESI指向源串,而ES:EDI指向目标串
EBP:基址指针(BASE POINTER),经常被用作高级语言函数调用的"框架指针"
(frame pointer).在破解时,经常可以看到一个标准函数的起始代码:
push ebp; 保存当前ebp
mov ebp,esp; EBP设为当前堆栈指针
sub esp,xxx; 预留xxx直接给函数临时变量
......
这样EBP构成了该函数框架,在EBP上方分别是原来的EBP,返回地址和参数. EBP下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可
ESP专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小.在32位平台上,ESP每次减少4字节.
ESP:寄存器存放当前线程的栈顶指针
EBP:寄存器存放当前线程的栈底指针
EIP:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行
1: // 基本程序运算.cpp : Defines the entry point for the console application.
2: //
3:
4: #include "stdafx.h"
5:
6: #include <stdio.h>
7: void main()
8: {
00401010 push ebp //将EBP压入栈中
00401011 mov ebp,esp //将现有的栈顶指针给EBP
00401013 sub esp,4Ch //给ESP分配x4C大小的空间给函数临时变量
00401016 push ebx
00401017 push esi
00401018 push edi //保存寄存器环境
00401019 lea edi,[ebp-4Ch] //用EBP-4Ch偏移量定位到我们定义的变量
0040101C mov ecx,13h //-4Ch是用来定位到栈顶,把堆栈内容改成int3中断以免内存泄露
00401021 mov eax,0CCCCCCCCh //以上操作是保存堆栈环境,分配堆栈空间
00401026 rep stos dword ptr [edi]
9: int x = 1;
00401028 mov dword ptr [ebp-4],1 //[ebp-4]是变量x,dword ptr表示x是DWORD类型(整型)
10: int y = 2;
0040102F mov dword ptr [ebp-8],2
11: int z = 3;
00401036 mov dword ptr [ebp-0Ch],3
12:
13: x++;
0040103D mov eax,dword ptr [ebp-4]
00401040 add eax,1
00401043 mov dword ptr [ebp-4],eax
14: y--;
00401046 mov ecx,dword ptr [ebp-8]
00401049 sub ecx,1
0040104C mov dword ptr [ebp-8],ecx
15: z /= x; // z = z/x;
0040104F mov eax,dword ptr [ebp-0Ch]
00401052 cdq
00401053 idiv eax,dword ptr [ebp-4]
00401056 mov dword ptr [ebp-0Ch],eax
16: z %= x; // z = z%x;
00401059 mov eax,dword ptr [ebp-0Ch]
0040105C cdq
0040105D idiv eax,dword ptr [ebp-4]
00401060 mov dword ptr [ebp-0Ch],edx
17: printf("%d, %d, %d/r/n", x, y, z);
00401063 mov edx,dword ptr [ebp-0Ch]
00401066 push edx
00401067 mov eax,dword ptr [ebp-8]
0040106A push eax
0040106B mov ecx,dword ptr [ebp-4]
0040106E push ecx
0040106F push offset string "%d, %d, %d/r/n" (0042201c) //传递参数
00401074 call printf (004010f0) //调用printf函数打印结果
00401079 add esp,10h //C调用的堆栈平衡
18:
19: x = x + y;
0040107C mov edx,dword ptr [ebp-4]
0040107F add edx,dword ptr [ebp-8]
00401082 mov dword ptr [ebp-4],edx
20: z -= x; // z = z-x;
00401085 mov eax,dword ptr [ebp-0Ch]
00401088 sub eax,dword ptr [ebp-4]
0040108B mov dword ptr [ebp-0Ch],eax
21: printf("%d, %d, %d/r/n", x, y, z);
0040108E mov ecx,dword ptr [ebp-0Ch]
00401091 push ecx
00401092 mov edx,dword ptr [ebp-8]
00401095 push edx
00401096 mov eax,dword ptr [ebp-4]
00401099 push eax
0040109A push offset string "%d, %d, %d/r/n" (0042201c) //传递参数
0040109F call printf (004010f0) //调用printf函数打印结果
004010A4 add esp,10h //C调用的堆栈平衡
22: }
004010A7 pop edi //恢复寄存器环境
004010A8 pop esi
004010A9 pop ebx
004010AA add esp,4Ch //平衡堆栈
004010AD cmp ebp,esp
004010AF call __chkesp (00401170) //DEBUG 模式程序专用的堆栈检查函数
004010B4 mov esp,ebp
004010B6 pop ebp
004010B7 ret
2.逻辑、关系运算
逻辑运算 &&(与) ||(或) !(非)
关系运算 > >= < <= == !=