Loading... # 寄存器 <span style="color:#DC143C">注意:寄存器是在CPU中的</span> X16 ![image-20201013082704844.png](http://www.irohane.top/usr/uploads/2021/03/703567054.png) X86 ![image-20201013082913278.png](http://www.irohane.top/usr/uploads/2021/03/1413693248.png) EAX: 累加寄存器,也用户ret之后的返回值 ECX: 计数器,使用rep或LOOP的时候用到 EDX: 一般用来存储除法产生的余数 EBX: 基地址寄存器,内存寻址存放寄存器 ESP: 一般用于栈顶 栈 从小往大 从上到下 EBP:用于栈低 ESI: 原操作数 EDI: 目的操作数 -------------------------64位 R8~R15 RCX RDX R8, R9 x64 Fastcall 会使用这些传参 # 控制寄存器 摘自:https://www.cnblogs.com/qq78292959/p/2600865.html CR0:包含了6个预定义标志,0位是保护允许位PE(Protedted Enable),用于启动保护模式,如果PE位置1,则保护模式启动,如果PE=0,则在实模式下。。。。。。 CR1: 未定义的控制寄存器,供将来的处理器使用。 CR2: 页故障线性地址寄存器,【缺页异常访问内存的时候可能在分页内存】 CR3:页目录基址寄存器 CR4: 是否开启 PAE 也保护 10 10 12 分页| 2 9 9 12 分页 # 调试寄存器 [转自](https://blog.csdn.net/whatday/article/details/8621410 "点击跳转") ![1362026458_3238.jpg](https://www.irohane.top/usr/uploads/2021/04/2671685605.jpg) DR0-DR3 这四个 寄存 器是用来设置 断点地址的。断点的比对在物理地址转换前(异常产生时,还没有将线性地址转换成物理地址)。由于只有0-3四个保存地址的 寄存 器,所以,硬件断点,在物理上最多只能有4个 DR4-DR5 这两个 调试 寄存 器有CR4的DE标记控制。如果DE置位,那么对这两个 寄存 器的访问会导致#UD异常。如果DE置0,那么他们就被化名为DR6-DR7 DR7 控制方式 | col1 | col2 | | - | - | | L0-L3 | DR0-DR3,设置断点作用范围,如果被置位,那么将只对当前任务有效。每次异常后,Lx都被清零。 | | G0-G3 | DR0-DR3,如果置位,那么所有的任务都有效。每次异常后不会被清零。 | | LE,GE | 在P6以下系列CPU上不被支持,cpu将会追踪精确的数据断点。LE是局部的,GE是全局的。 | | GD | 如果置位,追踪下一条指令是否会访问 调试 寄存 器。如果是,产生异常。在下面的DR6里面, | | R/W0-R/W3 | 00-执行断点、01-数据写入断点、10-I/0读写断点、11-读写断点 | DR6(调试状态) B0-B3(DR0-DR3):DRx指定的断点在满足DR7指定的条件下,产生异常。那么Bx就置位 BD:BD需要DR7的GD置位,才有效。BD是在下一条指令要访问到某一个 调试 寄存 器的时候,被置位的。 BS:单步执行模式时,被置位。单步执行是最高权限的 调试异常。 BT:在任务切换的时候,被置位。但是必须在被切换去的任务的TSS段里面的T标记被置位的情况下才有效。 # 段寄存器 CS: 代码段 DS:数据段 SS: 堆栈段 ES:附加段 GS: 全局段寄存器 FS:标志段寄存器 # 标志位寄存器 ![image-20201013082728871.png](http://www.irohane.top/usr/uploads/2021/03/2752707649.png) ![image-20200901221804955.png](http://www.irohane.top/usr/uploads/2021/03/2397735955.png) CF:进位标志位。 OF: 溢出位 ZF: 判断0位 TF: 调试标志位。当TF=1时,处理器每次只执行一条指令,即单步执行 PF: 奇偶位结果所有bit中1的个数为偶数,那么PF=1,1的个数 为奇数则PF=0; SF: 符号标志位。相关指令执行后结果为负那么SF=1 IF:中断允许标志位。 如果为1,能响应中断否则屏蔽中断 DF: 方向寄存器0 si di 递增 1 si di 递减 AF: 辅助进位标志位 # 汇编中寻址方式 ![image-20201014184241346.png](http://www.irohane.top/usr/uploads/2021/03/2262365045.png) # 指令 ![image-20201013083009115.png](http://www.irohane.top/usr/uploads/2021/03/2659783470.png) ## 数据传输指令 ![image-20201013083055090.png](http://www.irohane.top/usr/uploads/2021/03/1331835160.png) ## 算数运算 ![image-20201013083144617.png](http://www.irohane.top/usr/uploads/2021/03/642625467.png) ## 位操作 ![image-20201013083215932.png](http://www.irohane.top/usr/uploads/2021/03/1453065452.png) ![image-20201013083236213.png](http://www.irohane.top/usr/uploads/2021/03/3473291288.png) ## 逻辑运算 ![image-20201013083310562.png](http://www.irohane.top/usr/uploads/2021/03/1651278670.png) ## 串操作 | 指令 | 操作数1 | 操作数2 | 执行操作 | 类比 | | - | - | - | - | - | | movsb/w/d | ES:[EDI] | DS:[ESI] | 将操作数2的值传到操作1中同时EDI ESI 自增1 | memcpy | | stosb/w/d | DS:[EDI] | | 将AL,Ax,EAX寄存器中的字节、字或者双字存储到目标寄存器 | memset | | lodsb/w/d | DS:[ESI] | | 将原操作数中的字节、字或者双子分别架子到AL,AX,EAX寄存器 | | | cmpsb/w/d | ES:[EDI] | DS:[ESI] | 比较第一个原操作数指定的字节、与第二个原操作数指定的字节并根据结果设置 EFLAGE 寄存器中的状态 | memcmp | | rep | | | 与传操作指令连用,重复执行串指令ecx,每执行一次 ecx -1,ecx为0或者ZF为0的时候结束重复 | | | repen | | | ECX=0 and ZF=1 | | | repe | 相等重复 | | ECX=0 and ZF=0 | | | CLD | | | 将方向寄存器 清0 | | | STD | | | 将方向寄存器 置为1 | | ## JCC ![image-20200901221741714.png](http://www.irohane.top/usr/uploads/2021/03/3134813966.png) ## 汇编中库 ![image-20201014184618372.png](http://www.irohane.top/usr/uploads/2021/03/2818953902.png) ![image-20201014184630868.png](http://www.irohane.top/usr/uploads/2021/03/3644753802.png) ![image-20201014184642597.png](http://www.irohane.top/usr/uploads/2021/03/2166647351.png) ![image-20201014184654589.png](http://www.irohane.top/usr/uploads/2021/03/2272768626.png) # OPCODE OP CODE 是汇编编译以后的二进制代码,E8 31880000 长度不定, ## 创建操作数类型描述 | 符号位 | 描述 | | - | - | | E | 操作数是REG/MEM,由ModRM提供寻址 | | G | 操作数REG,由MODRM的REG提供寻址 | | I | 操作数是IMM,立即数体现再OPCode | | M | 操作数是MEM,由ModRM提供寻址,且MOD!=11B | | a | word/dword,依赖指令前缀 | | b | byte 8位 | | w | word 16位 | | d | dword 32位 | | q | qword 64位 | | dq | double qword 十六字节 128位 | | v | word或dword或qword,依赖指令前缀 | | | | | | | | | | ## 指令格式 ![image-20201015191837951.png](http://www.irohane.top/usr/uploads/2021/03/2261883409.png) 前缀指令: ![image-20201015191857335.png](http://www.irohane.top/usr/uploads/2021/03/842189364.png) CODE域 ![image-20201015191929166.png](http://www.irohane.top/usr/uploads/2021/03/1007992348.png) MODR/M域 ![image-20201015191953147.png](http://www.irohane.top/usr/uploads/2021/03/1229772122.png) # C语言内联汇编 ## 混合汇编 ``` //只是用于示例 _asm push 0 _asm { mov eax,64h push eax } ``` ## 外联汇编 ``` //和C语言一样 64位 extern 'C' int add(int a,int b) //需要声明这个 在外部创建编写asm文件然后添加编译器在编译的时候生成链接 ``` 注意在右键项目依赖自定义依赖选择 asm 然后再.asm文件 第三项选择 ``` .asm 文件 .code ;PS这里 没有用R8 R9 数据寄存器 AddFun proc ;//声明 xor rax,rax add rax,rcx add rax,rdx ret AddFun endp end ``` 裸函数: ``` //空函数什么也不写 也会生成很多汇编代码 //裸函数 只有地址信息 没有加入任何汇编指令 void _declspec(naked)func2 { _asm //内联汇编代码 { mov eax,0x16 } } ``` ## 结构体 ``` ==定义== .data student STRUC 4 m_age int ? m_name dword ? m_instance byte "No",0 student end ==使用== student1 student <> / <20> student2 student <20,"bob","YES"> studnet3 student {20} ==数组定义== class1 student 25 dup(<20>) ==数组使用== mov eax,student1.m_age mov student1.age,eax lea eax,offset student1.age ``` # 扩展知识 ## 原码 反码 补码 -1 1000 0001 原码 -1 1111 1110 反码 除了符号位 都取反 -1 1111 1111 补码 在最小位补1 ***负数以补码的方式进行存储*** ***整数的 原码 反码 补码 都是一样的** * ## 运算符 ### 与 and > 两个位都为1,结果才为1 ### 或 or > 只要一个为1,就为1 ### 异或 ^ > 不一样才为1 ### 非 ~ > 0为1,1为0 > > 单目运算 ### 左移 << shl > 各二进制全部左移若干位,高位丢弃,低位补0 > > shl(<<) 1101 1000 左移两位为:0110 0000 ### 右移 >> shr > 各二进制位全部右移若干位,低位丢弃,高位补0,或者补符号位。shr > > sar 右移 高位补符号位 > > shr 右移 高位补0 > > C 语言需要 > > unsigned int a=10; //无符号 > > a >>2; > > 默认有符号 ## 计算器如何使用位运算 做运算 ### 加法 ![image-20200830145329986.png](http://www.irohane.top/usr/uploads/2021/03/4011433946.png) 如果有进位 使用左移 运算符 然后循环判断知道没有进位 ### 减法 ![image-20200830151027478.png](http://www.irohane.top/usr/uploads/2021/03/2401382157.png) ## 内存 ![image-20200830201404208.png](http://www.irohane.top/usr/uploads/2021/03/3750880867.png) 注意:4GB的内存是虚拟分配的并不是真正的【内核中被成为线性地址】,可以随着运行扩大,而不是已经分配4GB 当内存扩大的适合会映射到物理内存. ### 为什么为4GB呢 FFFF FFFF 寻址范围 ![image.png](http://www.irohane.top/usr/uploads/2021/03/4199710623.png) 4,294,967,296 【0也算地址】 byte kb MB GB ![image.png](http://www.irohane.top/usr/uploads/2021/03/226923249.png) ## 函数传参方式 | 调用约定 | 参数传递方式 | 平栈方式 | | | - | - | - | - | | cdcall | 从右向左 | 调用者平栈 | | | stdcall | 从右向左 | 被调用者平栈 | | | thiscall | 从右向左【ECX只要传递指针】 | 被调用者平栈 | 一半用于类、WindowsAPI等 | | fastcall | 从右向左【X86-ecx-edx传参】【x64-RCX-RDX-R8-R9传参】 | 被调用者平栈 | 因为用寄存器传参所以速度很快 | | nakedcall | 这种不太清除 | | | 最后修改:2021 年 04 月 06 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏