进制
进制的定义
十进制的定义:由十个符号组成,分别是0 1 2 3 4 5 6 7 8 9逢十进一
九进制的定义:由九个符号组成,分别是0 1 2 3 4 5 6 7 8逢九进一
等等 十六进制 八进制 十二进制以此类推。
课堂练习:
二进制 从0写到30
0 01 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111
10000 10001 10010 10011 10100 10101 10110 10111 11000 11001 11010 11011 11100 11101 11110
八进制 从0写到80
1 | 2 | 3 | 4 | 5 | 6 | 7 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
31 | 32 | 33 | 34 | 35 | 36 | 37 |
41 | 42 | 43 | 44 | 45 | 46 | 47 |
51 | 52 | 53 | 54 | 55 | 56 | 57 |
61 | 62 | 63 | 64 | 65 | 66 | 67 |
71 | 72 | 73 | 74 | 75 | 76 | 77 |
101 | 102 | 103 | 104 | 105 | 106 | 107 |
111 | 112 | 113 | 114 | 115 | 116 | 117 |
根据表格计算八进制的加减乘除
1+1=2 | ||||||
1+2=3 | 2+2=4 | |||||
1+3=4 | 2+3=5 | 3+3=6 | ||||
1+4=5 | 2+4=6 | 3+4=7 | 4+4=10 | |||
1+5=6 | 2+5=7 | 3+5=10 | 4+5=11 | 5+5=12 | ||
1+6=7 | 2+6=10 | 3+6=11 | 4+6=12 | 5+6=13 | 6+6=14 | |
1+7=10 | 2+7=11 | 3+7=12 | 4+7=13 | 5+7=14 | 6+7=15 | 7+7=16 |
1*1=1 | ||||||
1*2=2 | 2*2=4 | |||||
1*3=3 | 2*3=6 | 3*3=11 | ||||
1*4=4 | 2*4=10 | 3*4=14 | 4*4=20 | |||
1*5=5 | 2*5=12 | 3*5=17 | 4*5=24 | 5*5=31 | ||
1*6=6 | 2*6=14 | 3*6=22 | 4*6=30 | 5*6=36 | 6*6=44 | |
1*7=7 | 2*7=16 | 3*7=25 | 4*7=34 | 5*7=43 | 6*7=52 | 7*7=61 |
八进制加减乘除
277 276 236 234
- 333 * 54 - 64 / 4
632 1370 152 47
+ 1666
20250
小小插曲
今天刚开始学习汇编语言,讲的是进制的转换与运算,本来觉得不以为意,因为在校期间我学习过计算机组成原理这门课程,觉得无非就是补码,反码之类的转化,然后进行运算,结果当老师问出八进制的2-3等于多少的时候整个人都有点蒙了,得到答案之后更蒙了,于是赶紧进行了学习。
Byte 一个字节 8位
Word 两个字节(字) 16位
Dword 四个字节(双字) 32位
两个二进制数表示一个字节
Windows操作系统数据存储高位在前低位在后
PE文件结构:
为什么要了解PE文件结构:
如果想分析一个程序 ,那么有几件事必须做:
-
程序是从哪里开始执行的
-
代码存在哪里
-
数据存在哪里
二进制的逻辑运算
或(or |)有一则为一
与(and &)全一才为一
异或(xor ^) 不一样为一
非(not !)1是0 ,0是1
左移:<< 0010 << 0100
计算机如何进行2+3?
X:0010 Y:0011
0010
xor 0011
0001 R:0001
检验:
0010
and 0011
0010
Z:0010 << 1 == 0100(判断是否为0 ,为零则R为运算结果)
不为零则
R→X:0001
Z→Y:0100
0001
Xor 0100
0101 R:0101
0001
And 0100
0000
0000 << 1 == 0000 运算结束
结果为R:0101 5
加密
例:
客户端:2015
密钥:54
20 15
00100000
Xor 01010100
01110100
20→74
同理 15→41
解密
例:
服务器端:7441
密钥:54
01110100
Xor 01010100
0010 0000 20
74→20
同理 41→15
通用寄存器的使用(EAX/ECX/EDX/EBX)
EAX、ECX、EDX、EBX为数据寄存器;
ESP、EBP为指针寄存器;
ESI、EDI变址寄存器。
-
EAX:累加器(Accumulator),操作数和结果数据累加器;
-
·ECX:计数(Counter),字符串和循环操作的计数器;
-
·EDX:用于保存乘法形成的部分结果或者除法之前部分被除数;
-
·ESP:堆栈(Stack)指针,被形象地称为栈顶指针;
-
·EBP:基址指针(BASE POINTER), SS段的数据指针;
-
·ESI:字符串操作的源(Source)指针,SS段的数据指针;
-
·EDI:字符串操作的目标(Destination)指针,ES段的数据指针.
MOV EAX,123456(把后边的值(123456)放到容器(EAX)里,其中123456叫做立即数)
小实验
内存
-
每个内存单元的宽度为8;
-
【编号】称为地址;
-
地址的作用:当我们想从内存中读取数据或者想向内存中写入数据,首先应该找到要读写的位置。
1K=1024个字节
32位计算机最大寻址宽度为4G
FFFFFFFF+1=100000000(八进制)
转为十进制为 4294967296(字节)
4194304(kb) 4096(M) 4(G)
内存的读写
寻址公式一:【立即数】
读取内存的值:
MOV EAX,DWORD PTR DS:[0X13FFC4]
MOV EAX,DWORD PTR DS:[0X13FFC8]
向内存中写入数据:
MOV EAX,DWORD PTR DS:[0X13FFC4],EAX
MOV EAX,DWORD PTR DS:[0X13FFC8],EBX
获取内存编号:
LEA EAX,DWORD PTR DS:[0X13FFC4]
LEA EAX,DWORD PTR DS:[ESP+8]
寻址公式二: 【reg】 reg代表寄存器 可以是8个通用寄存器中的任意一个
读取内存的值:
MOV ECX,0X13FFD0
MOV EAX,DWORD PTR DS:[ECX]
向内存中写入数据:
MOV EDX,0X13FFD8
MOV DWORD PTR DS:[EDX],0X87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EDX]
MOV EAX,DWORD PTR DS:[EDX]
寻址公式三:【reg+立即数】
读取内存的值:
MOV ECX.0X13FFD0
MOV EAX,DWORD PTR DS:[ECX+4]
向内存中写入数据:
MOV EDX,0X13FFD8
MOV DWORD PTR DS:[EDX+0XC],0X87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EDX+4]
MOV EAX,DWORD PTR DS:[EDX+4]
寻址公式四:【reg+reg*{1,2,4,8}】
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4]
向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4],87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4]
寻址公式五:【reg+reg*{1,2,4,8}+立即数】
读取内存的值:
MOV EAX,13FFC4
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4+4]
向内存中写入数据:
MOV EAX,13FFC4
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4+4],87654321
获取内存编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4+2]
堆栈
-
堆栈的本质就是内容;
-
栈是用来存储临时变量,函数传递的中间结果;
-
操作系统维护的,对“程序员”是透明的。
栈顶(ESP)栈底(EBP)
小实验
执行下面的指令,观察ESP/EBP的变化:
Push 0x123456
Push eax
Push ebx
Pop eax
Pop ebx
Pop ecx
变形的艺术
Push eax代码相当于:
Lea esp,dword ptr ss:[esp-4]
Mov dword ptr ss:[esp],eax
或者
Mov dword ptr ss:[esp-4],eax
Lea esp,dword ptr ss:[esp-4]
Lea esp,dword ptr ss:[esp-4] == mov esp.esp-4 == sub esp,4
Pop ecx代码相当于:
Mov ecx,dword ptr ss:[esp]
Lea esp,dword ptr ss:[esp+4] == mov esp,esp+4 == add esp,4
或者
Lea esp,dword ptr ss:[esp+4]
Mov ecx,dword ptr ss:[esp-4]
课后练习:
Push esp还可以写成哪种方式?Pop esp呢?
stos指令
Stos指令的作用是将eax中的值拷贝到EDI指向的地址:
MOV EAX,12345678
LEA EDI,DWORD PTR SS:[ESP]
STOS DWORD PTR ES:[EDI]
REP指令的目的是重复,ECX的值是重复的次数;
MOV EAX,0X22222222
MOV ECX,2
LEA EDI,DWORD PTR SS:[ESP]
REP STOS DWORD PTR ES:[EDI]
CLD(clear direction flag);
如果设置了direction flag,那么EDI会在该指令执行后减小
STD(set direction flag);
如果没有设置direction flag,那么EDI的值会增加。
课后作业:
画出下面指令执行时的堆栈图:
PUSH EBP
MOV EBP,ESP
SUB ESP,40
PUSH EBX
PUSH ESI
PUSH EDI
LEA EDI,DWORD PTR SS:[EBP-40]
MOV ECX,10
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]
[ESP]
STOS DWORD PTR ES:[EDI]
REP指令的目的是重复,ECX的值是重复的次数;
MOV EAX,0X22222222
MOV ECX,2
LEA EDI,DWORD PTR SS:[ESP]
REP STOS DWORD PTR ES:[EDI]
CLD(clear direction flag);
如果设置了direction flag,那么EDI会在该指令执行后减小
STD(set direction flag);
如果没有设置direction flag,那么EDI的值会增加。
课后作业:
画出下面指令执行时的堆栈图:
PUSH EBP
MOV EBP,ESP
SUB ESP,40
PUSH EBX
PUSH ESI
PUSH EDI
LEA EDI,DWORD PTR SS:[EBP-40]
MOV ECX,10
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]