80386汇编知识
本文主要是博主学习漏洞银行(BugBank)k1ght主讲的暴力流学汇编的内容
- 与汇编语言略有不同,是一门全新的编程语言,尽管继承了汇编语言的语法.
处理器的工作模式:
80386以后的处理器均有三种工作模式:实模式,保护模式和虚拟8086模式,我们一般所用的是保护模式.实模式和保护模式完全是为了向下兼容而设计,保护模式下,32位的cpu寻址才能达到4GB的地址空间,也才有内存分页管理,优先级保护,多任务等机制
80836寄存器
通用寄存器(EAX EBX ECX EDX,ESP,EBP,ESI,EDI)
通用寄存器与8086的寄存器相比,由16位变为了32位
ESP:栈顶
EBP:栈底
EAX,EBX,ECX,EDX通用寄存器
EAX:累加器(乘法的时候存低位)
EBX:基址([EBX+100H])
ECX:计数(循环的时候计数)
EDX:数据(默认EDX*10H+...;乘法的时候存高位)
ESI,EDI:变址寄存器
ESI:源变址寄存器
EDI:目的变址寄存器 与EBX基址搭配使用
段寄存器(CS SS DS ES FS GS)|段选择子
段寄存器依然是16位,寻求段地址的方式也因此发生了一点变化
CS:代码段寄存器
SS:堆栈段寄存器
DS:数据段寄存器
ES:附加数据段寄存器
FS:附加数据段寄存器
GS:附加数据段寄存器
这些段寄存器存放的不再是某个段的基地址,而是某个段的选择符(selector).因为16位的寄存器无法存放32位的段基地址,段基地址只好存放在段的描述符中(descriptor)中;
1.头两位是特权级字段 一共能表示0-3四个等级,程序的特权级要不低于改段寄存器的特权级才能够访问读取改段寄存器;0是最高级,3为一般程序的级别
2.TI:指定包含段描述符的描述符表是在GDT(TI=0)还是在LDT(TI=1)
3.index:14位的索引字段可以识别的段从0至16383,一共16384个段
指令寄存器和标志寄存器(EIP EFLAGS)
EIP:指令寄存器
CX(段寄存器)找到某个段的段地址后,再由EIP中存放的下一条要执行指令的偏移量(offset),二者联合找到指令地址;EIP中的偏移量是根据正在运行的代码段寄存器CS而言的.偏移量加上当前代码段的基地址,就形成了下一条指令的地址;
EFLAGS:
FLAG->EFLAG,16位的标志寄存器变为了32位的寄存器
1.
OF:溢出标志位.当补码运算有溢出时,OF=1否则为0
SF:符号标志位,他和运算结果的最高位相同
ZF:若当前运算结果位0则ZF=1;否则ZF=0;
AF:辅助进位标志.当执行一个加法或减法运算时结果中有借位或者进位AF=1;否则AF=0;
PF:奇偶标志位.反应运算结果中(二进制)1的个数是偶数还是计数.当执行结果中有偶数个1时,PF=1;否则PF=0;
CF:表示进位标志,当执行一个加法进位或一个减法借位时,CF=1;否则为0
2.下面三个可以用来控制CPU的操作,由指令进行置位和复位
DF:方向标志位.用以指定字符串处理的方向,该位置为1时,字符串以递减顺序处理,地址由高到低递减;反之,则递增;
IF:中断允许标志位.来控制是否允许接受外部中断请求
(IF的状态不影响非屏蔽中断请求和CPU内部中断请求.
TF:跟踪标志位;当该位为1时,CPU处于单步调试状态,此时CPU每执行完一条指令就自动产生一次内部中断,当改位复位后,CPU恢复正常工作;
这几个寄存器在8086中就已经存在
VM:表示虚拟8086模式;若VM被置位且80386已经处于保护模式下,则CPU切换到虚拟8086模式,此时,对段的任何操作又回到了实模式,如同在8086下运行一样`(逆向过程中不太常用)
系统地址寄存器(GDTR IDTR LDTR TR )描述符寄存器
1.全局描述符表寄存器GDTR:48位寄存器,用来保存全局描述符表(GDT)的32位基址和GDT的大小(16位)
2.中断描述符表寄存器IDTR:48位寄存器,用来保存中断描述符表(IDT)的32位基地址和IDT的大小(16位)
3.局部描述符表寄存器LDTR:16位寄存器,保存描述符表LDT段的选择符
4.任务状态寄存器TR:16位寄存器,用于保存任务状态段TSS段的16位选择符
…
控制寄存器(CR0 CR1 CR2 CR3 CR4)
调试寄存器(DR0 DR1 DR2 DR3 DR4 DR5 DR6 DR7 DR8)
CE测试寄存器(TR6 TR7)
寻址方式
- 实模式寻址方式(与8086下的寻址方式很像)
CS:IP ------CS*10H+IP
DS:[bx]------DS*10H+IP
- 保护模式寻址方式
GDT和LDT:
1.每个程序都有自己的LDT,但是同一台计算机上的所有程序共享一个GDT
2.有关GDT(http://www.cnblogs.com/longintchar/p/5224406.html):
全局描述符表的引入:与实模式相同的是,保护模式下对内存的访问依然是段地址*10h+偏移地址,但保护模式下每个段访问前,必须先登记,要为这个段建立一个描述符.每个描述符占八个字节,这些描述符集存放在某个内存区域,"一个挨着一个,就构成了一张表.
保护模式下寻址大概过程
段选择器又称段选择子
1.首先判断段选择器(16位的段寄存器)中第TI位为0还是1
2.(GDT的具体位置由GDTR记载)
如果TI=0,则13位的索引信息Index索引的就是GDT表(GDT表的相关信息由GDTR来确定)中的描述符
如果TI=1,则根据16位LDTR中的索引信息找到LDT在GDT中所对应的位置
再由选择器(段寄存器)中的索引信息找到相应的描述符
3.由描述符找到具体的32位的基址,即段地址.
4.最后由段地址+32位的的偏移地址寻得保护模式下的虚拟地址.
80836储存器寻址
如 mov eax,[esp] 由ss的索引值等找到描述符再找到基址再+esp 将这个地址的值赋给eax
数据传送指令
一.通用数据传送指令
1 .mov 指令
- 下图为数据允许传送的方向
- 传送操作不影响标志位
2.扩展传送指令
MOVSX与MOVZX:讲8位操作数扩展为16位操作数,或将16位操作数扩展为32位操作数.其中MOVSX是按有符号数扩展,MOVZX则是按无符号数扩展.无符号数或正数高位扩展为0,负数高位扩展为全1
3.交换指令
(1)格式:XCHG OPR1,OPR2
功能:交换两个操作数的值
如:
XCHG AX,B
(2)
二.堆栈传送指令
三.地址传送指令
四.标志寄存器传送指令
算术运算指令
80x86指令包括加减乘除四种基本算术运算操作以及十进制运算调整指令
二进制加减法指令
带符号操作数采用补码表示,无符号数和带符号数的运算可以使用相同的指令
二进制乘除法分带符号数和无符号数运算
- 加法指令,减法指令,加1减1指令
- 比较指令,交换相加指令,求补指令
- 乘法指令,除法指令
加法指令
减法指令
加1减1指令
比较指令
交换相加指令
求补指令
乘法指令
除法指令
逻辑运算指令
- 与指令
- 或指令
- 异或指令
. - 非指令
- 移位指令
控制转移指令
- 无条件转移指令
2. 条件转移指令
串操作指令和处理器操作指令
处理器操作