汇编部分
进制
进制的定义
十进制的定义:由十个符号组成,分别是0 1 2 3 4 5 6 7 8 9 逢十进一。
九进制的定义:由九个符号组成,分别是0 1 2 3 4 5 6 7 8 逢九进一。
十六进制的定义:由十六个符号组成,分别是0 1 2 3 4 5 6 7 8 9 A B C D E F
进制运算的本质是查表
例:
通用寄存器
在x86 32位系统的情况下,常见的寄存器如下
寄存器 | 编号(二进制) | ||
---|---|---|---|
32位 | 16位 | 8位 | |
EAX | AX | AL | 000 |
ECX | CX | CL | 001 |
EDX | DX | DL | 010 |
EBX | BX | BL | 011 |
ESP | SP | AH | 100 |
EBP | BP | CH | 101 |
ESI | SI | DH | 110 |
EDI | DI | BH | 111 |
他们之间的关系如下:
所有的寄存器都可以看作是一个容器,当然,特定时候有特殊的用法
32位通用寄存器的指定用途如下:
寄存器 | 主要用途 | 编号 | 储存数据范围 |
---|---|---|---|
EAX | 累加器 | 0 | 0 - 0xFFFFFFFF |
ECX | 计数 | 1 | 0 - 0xFFFFFFFF |
EDX | I/O指针 | 2 | 0 - 0xFFFFFFFF |
EBX | DS段的数据指针 | 3 | 0 - 0xFFFFFFFF |
ESP | 栈顶指针 | 4 | 0 - 0xFFFFFFFF |
EBP | 栈底指针 | 5 | 0 - 0xFFFFFFFF |
ESI | 字符串操作的源指针,SS段的数据指针 | 6 | 0 - 0xFFFFFFFF |
EDI | 字符串操作的目标指针,ES段的数据指针 | 7 | 0 - 0xFFFFFFFF |
标志寄存器
标志寄存器是一些特殊的寄存器,用来存放逻辑运算的结果标志,构成如下图:
几个比较重要的标志寄存器作用:
1、进位标志CF(Carry Flag):如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。
2、奇偶标志PF(Parity Flag):奇偶标志PF用于反映运算结果中“1”的个数的奇偶性,如果“1”的个数为偶数,则PF的值为1,否则其值为0。
3、辅助进位标志AF(Auxiliary Carry Flag):
在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
(1)、在字操作时,发生低字节向高字节进位或借位时;
(2)、在字节操作时,发生低4位向高4位进位或借位时。
4、零标志ZF(Zero Flag):零标志ZF用来反映运算结果是否为0。
如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。
5、符号标志SF(Sign Flag):符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。
6、溢出标志OF(Overflow Flag):溢出标志OF用于反映有符号数加减运算所得结果是否溢出。 如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。
寄存器与内存的关系
寄存器位于CPU内部,执行速度快,但比较贵。
内存速度相对较慢,但成本较低,所以可以做的很大。
寄存器和内存没有本质区别,都是用于存储数据的容器,都是定宽的。
寄存器常用的有8个:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI。
计算机中的几个常用计量单位:BYTE WORD DWORD
内存的数量特别庞大,无法每个内存单元都起一个名字,所以用编号来代替,我们称计算机CPU是32位或者64位,主要指的就是内存编号的宽度,而不是寄存器的宽度。
内存编号如下图:
1 | 0x00000000 |
32位计算机的编号最大是32位,也就是32个1 换成16进制为FFFFFFFF,也就是说,32位计算机内存寻址的最大范围是FFFFFFFF+1
内存的单位是字节,那内存中能存储的信息最多为:FFFFFFFF+1 字节 即4G,这也是为什么我们在一个XP的系统上面如果物理内存超过4G是没有意义的原因。
但是不是所有的32位计算机最多识别的内存为4g,如果装了某种驱动或者其他情况,可以超过4g。
堆栈
堆栈优点:
1 | 堆栈的优点:临时存储大量的数据,便于查找. |
什么是堆栈:
1 | 1、BASE,TOP是2个32位的通用寄存器,里面存储的是内存单元编号(内存地址). |
根据上面的定义,不用push和pop一样可以实现堆栈的功能(取数据和存数据)
汇编指令
在x86 32位系统的环境下,常见汇编指令如下:
MOV 指令0x00000000
0x00000001
0x00000002
….
….
….
….
….
….
0xFFFFFFFF
作用:拷贝源操作数到目标操作数
用法:
1 | MOV r/m8,r8 r 通用寄存器 |
往内存中写入数据具体用法如下:
1 | 1、内存格式 |
ADD指令
作用:将源操作数和目标寄存器的值相加并保存到目标寄存器
用法:
1 | ADD AL, imm8 |
SUB指令
作用:将源操作数和目标寄存器的值相减并保存到目标寄存器
用法:
1 | SUB AL, imm8 |
AND指令
作用:将源操作数和目标寄存器的值进行与运算并保存到目标寄存器
用法:
1 | AND AL, imm8 |
OR指令
作用:将源操作数和目标寄存器的值进行或运算并保存到目标寄存器
用法:
1 | OR AL, imm8 |
XOR指令
作用:将源操作数和目标寄存器的值进行异或运算并保存到目标寄存器
用法:
1 | XOR AL, imm8 |
NOT指令
作用:将目标寄存器的值进行非运算并保存到目标寄存器
用法:
1 | NOT r/m8 |
LEA指令
作用:获取目标内存地址编号并存到指定位置
用法:
1 | LEA EAX,DWORD PTR DS:[EAX+ECX*4] |
PUSH指令
作用: 压栈,将一个数或者寄存器中的值压入堆栈中
用法:
1 | PUSH r32 |
POP指令
作用: 出栈,将某个内存的zhi值取出放入某个寄存器中
用法:
1 | POP r32 |
jcc汇编指令
jcc指令的本质是修改EIP寄存器的值
JMP指令
作用:修改EIP的值
用法:
1 |
|
PUSH 地址B
MOV EIP,地址A/寄存器 简写为:CALL 地址A/寄存器
1 | ### RET指令 |
CMP指令
作用:该指令是比较两个操作数,实际上,它相当于SUB指令,但是相减的结构并不保存到第一个操作数中。 只是根据相减的结果来改变零标志位的,当两个操作数相等的时候,零标志位置1。
用法:
1 | CMP R/M,R/M/IMM |
TEST指令
作用:该指令在一定程序上和CMP指令时类似的,两个数值进行与操作,结果不保存,但是会改变相应标志位.
用法:
1 | TEST R/M,R/M/IMM |