386汇编基础知识笔记

寄存器
1.8个通用寄存器都可用于基址变址寻址,当做指针寄存器使用,这是不同于8086的(8086只能是bx、si、di、bp)
2.六个段寄存器:cs、ds、ss、es、fs、gs
3.32位标志寄存器eflags
新增4个标志:
(1)io特权标志iopl:2位宽,指定了执行i/o指令所需的特权级,如果当前特权级小于等于该值,则i/o=指令可被执行,否则引发保护异常。
(2)位14。嵌套任务标志nt:控制iret的执行
nt=0,常规返回(pop eflags 、pop eip、pop cs)
nt=1,通过任务转换实现中断返回(不太理解。。。)
(3)位16。重启动标志rf:控制是否接受调试故障。
rf=0    接受
rf=1    忽略
成功执行每一条指令后,cpu对rf位清0.接收到一个非调试性故障时置1.
(4)位17。虚拟8086方式标志vm:
vm=1:在虚拟8086方式下工作
vm=0:在保护模式下工作

存储器寻址:
1.保护模式下,段寄存器存储段选择子,间接指示段基地址
2.默认段寄存器的选择只受基址寄存器影响。
3.如果某一存储器操作数的地址是该操作数尺寸(所占字节数)的倍数,那么称该操作数对齐。访问对齐的数较快。

386指令集:
1.数据传送指令:
(1)通用传送指令:mov movsx movzx xchg push pusha pushad pop popa popad
movsx和movzx用法:
movsx dst,src
dst必须为reg16、reg32,src可以reg8、reg16,也可以是存储器单元
push指令与8086的不同点:可以push立即数,而且支持push 32位值
80386push sp或esp时:将push前的sp或esp值压栈。
pushad:将8个32位通用寄存器压入堆栈
顺序:eax ecx edx ebx esp ebp esi edi
然后esp减32,所以压入的esp值是pushad之前的esp值
popad:与pushad相反,但esp的恢复是通过加32实现,不是弹栈实现
(2)地址传送指令:
lea妙用:可以用lea做计算
lea eax,[ecx+esi*4+1234h]    lea的作用是将内存操作数的地址传入寄存器,在这里[]中是操作数地址,该指令事实上计算了ecx+esi*4+1234h,并存入eax。
装入指针指令:lds les lfs lgs lss
用法:lds reg,oprd
(3)标志传送指令:
pushfd    popfd    push和pop32位eflags
(4)累加器专用传送指令:in out xlat
in和out和8086一样,但可以输入输出一个双字
xlat    表转换指令,未学,,有待查资料了解用法。。。。
2.算术运算指令:
(1)加减指令:neg未学,有待查询。。
(2)乘除指令:mul div imul idiv
与8086相同,只是操作数位数相应变大
imul指令特殊用法:
imul dst,src
imul dst,src1,src2
格式1:两者相乘存入dst。格式2:src1和src2相乘存入dst
dst:reg16或reg32.
格式1:src长度必须和dst长度相同(8位立即数除外),可以是寄存器、存储器单元、立即数
格式2:src1只能是寄存器或存储单元,并且长度必须和dst长度相同,src2只能是立即数。
(3)符号扩展指令:cbw cwd cwde cdq
(4)十进制调整指令:daa das aaa aas aam aad
3.逻辑运算和移位指令:
(1)逻辑运算指令:not and or xor test
(2)一般移位指令:
算术移位:sal sar
逻辑移位:shl shr
sal和shl相同
和8086相比,移位位数可以是8位立即数。80386移位位数实际是移位位数的低5位。即范围:0——31
(3)循环移位指令:rol ror rcl rcr
用到再说。。。
(4)双精度移位指令:
用到再说。。。
4.控制转移指令:
(1)转移指令组:
jecxz    仍用1字节表示地址差值
(2)循环指令组:loop loopz loopnz loope
用ecx做计数器
(3)过程调用和返回指令
(4)中断调用和返回指令
5.串操作指令:
(1)基本串操作:lodsd stosd movsd scansd cmpsd
(2)rep repz/repe repnz/repne
(3)串输入:
insb    输入字节
insw    输入字
insd    输入双字
串输入指令从由dx给出端口地址的端口读入一字符,并送入es:edi所指的目的串中,同时根据df和字符类型调整edi。
一般与rep连用,实现连续输入,但必须主意端口的数据准备情况。
(4)串输出:
outsb
outsw
outsd
从ds:esi所指源串读取一个字符,输出到由dx给出端口地址的端口,同时根据df和字符类型调整esi。
6.高级语言支持指令:bound enter leave
enter cnt1,0相当于:
push ebp
mov ebp.esp
sub esp,cnt1
leave则相反
bound    检查数组下标是否越界,越界则产生5号中断。
bound    oprd1,oprd2
oprd1为reg32,oprd2为64位存储器单元,低dd是起始下标,高dd是结尾下标
下面是示例:
num=100
array db num dup (0)
stv dd 0
edv dd num-1
……
bound si,fword ptr stv    ;si中是下标,如果si不在范围中,则引发int 5
mov al,array[si]
7.条件字节设置指令
SETcc oprd
oprd只能是reg8或内存字节单元
根据测试条件,置oprd为1
8.位操作指令
(1)位测试与设置指令
bt    位测试
btc    位测试并取反
btr    位测试并复位
bts    位测试并复位
格式:
xxx oprd1,oprd2
oprd1:reg32或内存双字数据,要测试的数据
oprd2:8位立即数或者与oprd1长度相等的寄存器,用于指定要测试的位(具体规则见书)
后3个指令都是将要测试的位送cf,然后设置标志寄存器相关位
感觉这个指令没有太大用处,,要测试的位是哪一位的寻找规则比较繁琐。
(2)位扫描指令:bsf bsr
不解释。。。
8.处理器控制指令
(1)设置标志指令组
(2)空操作指令:nop:占一个字节
(3)外同步指令和前缀
wait
等待直到busy引脚为高(怎么感觉像单片机。。呵呵,不过本来就是个高级的单片机)
busy引脚由数值协处理器控制。所以该指令实际上是等待协处理器以便与它同步。
封锁前缀lock
锁定目的操作数所在内存单元
可用lock前缀的指令如下:
xchg
add,adc,sub,sbb,neg,inc,dec
and,or,not,xor
bt,bts,btr,btc

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>