初学汇编

寄存器

存储数据速度:

复制代码
 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标志。