寄存器
存储数据速度:
cpu > 内存 > 硬盘
通用寄存器
寄存器是在cpu中的
8位 | 16位 | 32位 |
---|---|---|
EAX | AX | AL |
EBX | BX | BL |
ECX | CX | CL |
EDX | DX | DL |
ESP | SP | AH |
EBP | BP | CH |
ESI | SI | DH |
EDI | DI | BH |
内存地址的五种形式
1.立即数:如0x13FFC4
2.[reg] reg代表寄存器,可以是8个通用寄存器中的任意一个
3.[reg+立即数]
4.[reg+reg*{1,2,4,8}]
5.[reg+reg*{1,2,4,8}+立即数]
什么是堆栈
堆栈就是一块内存,操作系统在程序启动的时候就已经分配好了,供程序执行时使用
栈指针寄存器 ESP:在当中存储了当前的栈堆用到哪了
存储模式
在下面数据低位存储在低位,这个低位指的是内存地址,如0x00000000与0x00000001在这当中前者就是低位
1.小端存储模式(电脑使用多):数据低位在低位,数据高位在高位(其中数据的低位高位是按照从左到右的顺序,如0x1A2C,其中1A是高位,2C是低位)
2.大端存储模式(手机使用多):数据高位在低位,数据低位在高位
汇编指令
1.mov指令:
**粗略介绍:**
r代表通用寄存器,m代表内存,imm代表立即数,r8代表8位通用寄存器,m8代表8 位内存,imm8代表8位立即数
1.mov r/m8,r8
2.mov r/m16,r16
3.mov r/m32,r32
4.mov r8,r/m
5.mov r16,r/m16
6.mov r32,r/m32
7.mov r8,imm8
8.mov r16,imm16
9.mov r32,imm32
**详细介绍一下:**
1.立即数到寄存器 mov EAX,1
2.寄存器到寄存器 mov EAX,EDI (注意使用时的数据宽度是否一致,mov cl,bx会因为数据宽度不符合而不被允许)
3.立即数到内存 mov byte(这个是代表一个字节,如果需要更大的空间就写 dword等其他存储单位) ptr ds:[内存地址],1
4.寄存器到内存 mov dword ptr ds:[内存地址],EAX(注意:宽度必须是一致 的)
5.内存到寄存器 mov EAX,dword ptr ds:[内存地址]
2.movs指令
1.moves byte ptr es:[EDI],byte ptr ds:[ESI] 简写为:movesb
2.moves word ptr es:[EDI],byte ptr ds:[ESI] 简写为:movesw
1.moves dword ptr es:[EDI],byte ptr ds:[ESI] 简写为:movesd
3.以add指令(加运算)为例,SUB指令(减运算),and指令(与运算),or指令(或运算),xor(异或运算)都是将下面的add改为对应的指令名称
1.ADD r/m8,imm8
2.ADD r/m16,imm16
3.ADD r/m32,imm32
4.ADD r/m16,imm8
5.ADD r/m16,imm8
6.ADD r/m8,r8
7.ADD r/m16,r16
8.ADD r/m32,r32
9.ADD r8,r/m8
10.ADD r16,r/m16
11.ADD r32,r/m32
4.NOT指令(取反z)
1.NOT r/m8
2.NOT r/m16
3.NOT r/m32
5.stos指令:将AI/AX/EAX的值存储到[EDI]指定的内存单元
1.STOS BYTE PTR ES:[EDI] 简写为:STOSB
2.STOS word PTR ES:[EDI] 简写为:STOSW
3.STOS dword PTR ES:[EDI] 简写为:STOSD
6.REP指令:按计数寄存器(ECX)中指定的次数重复执行字符串指令
例如REP STOSD,他的执行次数取决于ECX中的数字(是十六进制的)
7,push指令:
作用:
1.向堆栈中压入数据
2.修改栈顶指针esp寄存器
用法:
1.push r32
2.push r16
3.push m16
4.push m32
5.push imm8/imm16/imm32
8.pop指令:
作用:
1.将栈顶数据存储到寄存器/内存
2.修改栈顶指针esp寄存器
用法:
1.pop r32
2.pop r16
3.pop m16
4.pop m32
9.JMP指令:
MOV EIP,寄存器/立即数/内存 简写为JMP 寄存器/立即数/内存
10.CALL指令:
push下一行地址,并且eip值为call后面的值
mov eip,寄存器/立即数/内存 简写为CALL 寄存器/立即数/内存
与jmp的唯一区别:
在堆栈中存储call指令的下一行地址
11.ret指令:
add esp,4
mov eip,[esp-4] 简写为ret
12.jcc指令
1.JE,JZ 结果为零时跳转(相等时跳转) ZF=1
2.JNE,JNZ 结果不为零时跳转(不相等时跳转) ZF=0
3.JS 结果为负则跳转 SF=1
4.JNS 结果为非负则跳转 SF=0
5.JP,JPE 结果中1的个数为偶数跳转 PF=1
6.JNP,JPO 结果中1的个数为奇数跳转 PF=0
7.JO 结果溢出了则跳转 OF=1
8.JNO 结果没有溢出则跳转 OF=0
9.JB,JNAE 小于则跳转(无符号数) CF=1
10.JNB,JAE 大于等于则跳转(无符号数) CF=0
11.JBE,JNA 小于等于则跳转(无符号数) CF=1 or ZF=1
12.JNBE,JA 大于则跳转(无符号数) CF=0 or ZF=0
13.JL,JNGE 小于则跳转(有符号数)SF不等于OF
14.JNL,JGE 大于等于则跳转(有符号数)SF=OF
15.JLE,JNG 小于等于则跳转(有符号数)ZF=1 or SF不等于OF
16.JNLE,JG 大于则跳转(有符号数)ZF=0 or SF=OF
函数
函数就是一系列指令的集合,为了完成某个会重复使用的特定功能。例如:向寄存器中赋值,参数较多的时候会使用堆栈
如何执行一个函数(即函数调用):
1.用jmp来执行函数
2.用call来执行函数
堆栈平衡
简单来说就是堆栈esp原本指在什么位置现在就回到什么位置
1.如果返回父程序,则当我们在堆栈中进行堆栈操作的时候,一定要保证在ret指令之前,esp指的是我们压入栈中的地址
2.如果通过堆栈传递数据了,那么在函数执行完毕之后,要平衡参数导致的堆栈变化
标志寄存器(EFLAGS)
1.CF(bit 0)[Carry flag]
若算数操作产生的结果在最高有效位发生进位或借位则将其置1,反之清零。这个标志通常用来指示无符号整型运算的溢出状态
2.PF(bit 2)[Parity flag]
如果结果的最低有效字节包含偶数个1位则该位置为1,否则清零
3.AF(bit 4)[Auxiliary Carry flag]
如果算术操作在结果的第三位发生进位或借位则将该标志置1,否则清零。这个表示在bcd算术运算中使用
4.ZF(bit 6)[Zero flag]
若结果为0则将其置为1,反之清零,经常与cmp或者test等指令一起使用(cmp指令相当于sub指令,但是相减的结果并不保存到第一个操作数中,test指令相当于add,但是相加的结果也不保存到第一个操作数中)
5.SF(bit 7) [Sign flag]
该标志被设置为有符号整型的最高有效位。(0指示结果为正,反之为负)
6.OF(bit 11)[Overflow flag]
溢出标志OF用于反映有符号加减运算所得出结果是否溢出
7.DF(bit 10)[Direction Flag]
这个方向标志控制字符串指令(movs,cmps,scas,lods以及stos)。设置DF标志使得串指令自动递减(从高地址向低地址方向处理字符串),清楚该标志则使得串指令自动递增。STD以及CLD指令分别用于设置以及清除DF标志。