寄存器
存储数据速度:
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:在当中存储了当前的栈堆用到哪了
存储模式
![[屏幕截图 2025-09-21 120600.png]]
在下面数据低位存储在低位,这个低位指的是内存地址,如0x00000000与0x00000001在这当中前者就是低位
1.小端存储模式(电脑使用多):数据低位在低位,数据高位在高位(其中数据的低位高位是按照从左到右的顺序,如0x1A2C,其中1A是高位,2C是低位)
2.大端存储模式(手机使用多):数据高位在低位,数据低位在高位
汇编指令
1.mov指令:**粗略介绍:**r代表通用寄存器,m代表内存,imm代表立即数,r8代表8位通用寄存器,m8代表8 位内存,imm8代表8位立即数1.mov r/m8,r82.mov r/m16,r163.mov r/m32,r324.mov r8,r/m5.mov r16,r/m166.mov r32,r/m327.mov r8,imm88.mov r16,imm169.mov r32,imm32**详细介绍一下:**1.立即数到寄存器 mov EAX,12.寄存器到寄存器 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] 简写为:movesb2.moves word ptr es:[EDI],byte ptr ds:[ESI] 简写为:movesw1.moves dword ptr es:[EDI],byte ptr ds:[ESI] 简写为:movesd3.以add指令(加运算)为例,SUB指令(减运算),and指令(与运算),or指令(或运算),xor(异或运算)都是将下面的add改为对应的指令名称1.ADD r/m8,imm82.ADD r/m16,imm163.ADD r/m32,imm324.ADD r/m16,imm85.ADD r/m16,imm86.ADD r/m8,r87.ADD r/m16,r168.ADD r/m32,r329.ADD r8,r/m810.ADD r16,r/m1611.ADD r32,r/m324.NOT指令(取反z)1.NOT r/m82.NOT r/m163.NOT r/m325.stos指令:将AI/AX/EAX的值存储到[EDI]指定的内存单元1.STOS BYTE PTR ES:[EDI] 简写为:STOSB2.STOS word PTR ES:[EDI] 简写为:STOSW3.STOS dword PTR ES:[EDI] 简写为:STOSD6.REP指令:按计数寄存器(ECX)中指定的次数重复执行字符串指令例如REP STOSD,他的执行次数取决于ECX中的数字(是十六进制的)7,push指令:
作用:1.向堆栈中压入数据2.修改栈顶指针esp寄存器
用法:1.push r322.push r163.push m164.push m325.push imm8/imm16/imm328.pop指令:
作用:1.将栈顶数据存储到寄存器/内存2.修改栈顶指针esp寄存器
用法:1.pop r322.pop r163.pop m164.pop m329.JMP指令:MOV EIP,寄存器/立即数/内存 简写为JMP 寄存器/立即数/内存10.CALL指令:push下一行地址,并且eip值为call后面的值mov eip,寄存器/立即数/内存 简写为CALL 寄存器/立即数/内存与jmp的唯一区别:在堆栈中存储call指令的下一行地址11.ret指令:add esp,4mov eip,[esp-4] 简写为ret12.jcc指令1.JE,JZ 结果为零时跳转(相等时跳转) ZF=12.JNE,JNZ 结果不为零时跳转(不相等时跳转) ZF=03.JS 结果为负则跳转 SF=14.JNS 结果为非负则跳转 SF=05.JP,JPE 结果中1的个数为偶数跳转 PF=16.JNP,JPO 结果中1的个数为奇数跳转 PF=07.JO 结果溢出了则跳转 OF=18.JNO 结果没有溢出则跳转 OF=09.JB,JNAE 小于则跳转(无符号数) CF=110.JNB,JAE 大于等于则跳转(无符号数) CF=011.JBE,JNA 小于等于则跳转(无符号数) CF=1 or ZF=112.JNBE,JA 大于则跳转(无符号数) CF=0 or ZF=013.JL,JNGE 小于则跳转(有符号数)SF不等于OF14.JNL,JGE 大于等于则跳转(有符号数)SF=OF15.JLE,JNG 小于等于则跳转(有符号数)ZF=1 or SF不等于OF16.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标志。