《汇编语言程序设计》易错知识,核心知识总结(第一,二章)

本文是主要基于钱晓捷的《汇编语言程序》第五版做出的易错知识,核心知识点总结。

8086指令系统:

一,数据传送类:

易错点:

        段寄存器之间不能传值,存储器之间不能传值,立即数不能直接传给段寄存器,立即数传给存储器需要显示指明存储器单元类型。

        数据传送类指令除标志寄存器传送指令(lahf,sahl,pushf,popf)外均不影响标志位

        MOV指令:

                mov reg/men, imm

                mov reg/men/seg, mem

                mov reg/seg, mem

                mov reg/men, seg

        XCHG指令:

                XCHG reg,reg/mem

                XCHG reg/mem,reg

        XLAT转码指令:

                xlat           ;al\leftarrowds:[bx+al]该指令默认使用BX,AL寄存器

        PUSH堆栈操作指令:操作对象只能式字操作数

                push r16/m16/seg  ;sp\leftarrowsp - 2, ss:[sp]\leftarrowr16/m16/seg

        POP堆栈操作指令:操作对象只能式字操作数

                pop r16/m16/seg  ;  r16/m16/seg\leftarrowss:[sp], sp\leftarrowsp + 2

                                                                8086处理器堆栈操作

堆栈的应用:

 标志传送指令:

1. 标志送AH指令 LAHF(LOAD AH FROM FLAGS)

2.AH送标志指令 SAHF(SAVE AH TO FLAGS)

3.标志进栈指令PUSHF

4.标志出栈指令POPF

算数运算类:

        状态标志:进位标志(针对无符号)CF=1,进位或借位,如何理解:比如字节数据相加减,结果不在0~255范围内,则CF=1。

                          溢出标志(针对有符号)OF=1,溢出。如何理解溢出:有符号正数相加,得到了负数,就说明溢出了  0110 0001 + 0100 0010 = 1010 0011。总结起来就是:只有当两个相同符号数相加(包含两个不同符号数相减)而运算结果的符号与原数据符号相反,才产生溢出。因为此时运算结果显然不对。两个正数相加怎么可能是负数?正数减负数怎么可能得负数?因为溢出了呀! 

     

 其他标志位如零标志ZF,运算结果为零时ZF=1;符号标志SF,运算结果为负数是SF = 1;奇偶标志PF,运算结果在1的个数为偶数时AF =1。

提醒一句:之前说到的数据传送类指令除了标志寄存器传送指令(lahf,sahl,pushf,popf)外均不影响标志位

现在开始介绍算术指令(按照+ - * / 的顺序):

add加法指令,add reg, imm/reg/mem  ;reg\leftarrowreg+imm/reg/mem

                        add mem,imm/reg

adc带进位加,即运结果还要加上CF的值

 

inc增量指令(加一运算),如:inc ax,设计目的是用于对计算器和地址指针的调用,不影响CF

sub减法指令,格式同add

sbb带借位减法指令,运算结果还要减去OF的值

dec减量指令,类似inc

neg求补指令,可以表示成:将操作数按位取反+1。对标志位的影响同add。

eg:neg reg/mem;    reg/mem\leftarrow0 - reg/mem

cmp比较指令,同sub一样执行同样的操作,影响标志位,但是结果不送入目的操作数

乘法指令

除法指令

提醒:乘法指令利用对OF,CF的影响可以判断相乘的结果的高一半是否含有有效数据,如果有OF=CF=1,如果没有,即高位为0,则OF=CF=0;对其他标志位没有定义,即为任意,但不代表不影响,可能在8086中没有定义的必要。除法指令类比理解。 

 符号扩展指令(针对有符号数设计,正数补1,负数补0)cbw将al符号扩展到ax,cwd将ax符号扩展到dx和ax寄存器对。

 

逻辑运算指令:(所有双操作数的逻辑指令均设置CF=OF=0,根据结果设置SF,ZF,PF的状态,而对AF没有定义),对两个操作数执行逻辑运算,结果送目的操作数

        AND逻辑与指令,两个操作数不能同时为存储器寻址,源操作数可以是任意寻址方式,目的操作数只能是立即数外的其他寻址方式。

        OR逻辑或指令

        XOR逻辑异或指令。xor  ax,ax;将ax设置为0

        NOT逻辑非指令,不影响标志位

        TEST测试指令,执行操作和AND一样,不保存结果,目的操作数不变,根据结果来影响标志位

移位指令:

        shl  reg/mem , 1/cl;逻辑左移,最低位补0,最高位进入CF,如下图所示

         shr  reg/mem , 1/cl

        sal  reg/mem , 1/cl;同shl

        sar  reg/mem , 1/cl;算数右移,最高位不变,最低位进去CF

移位指令按照移入的位设置进位标志CF,根据移位后的结果影响SF,ZF,PF对AF没有定义。如果进行1位移动,按照操作数的最高符号位是否改变,相应设置溢出标志OF,最高位改变OF=1,否则OF = 0;如果移位次数大于1时,OF不确定。

 

 循环移位指令:

        rol  reg/mem , 1/cl;不带进位循环左移

        ror  reg/mem , 1/cl

        rcl  reg/mem , 1/cl;带进位循环左移,具体操作见下图。

        rcr  reg/mem , 1/cl

前两条指令不降进位CF纳入循环位中。后两条纳入,即9位或者17位二进制数一起移动。循环移位指令按照功能设置进位CF,不影响其他标志位。

控制转移类

        1.无条件转移指令

                段内转移,相对寻址:JMP  lable;ip\leftarrowip+位移量

                段间转移,间接寻址:JMP  r16/m16;ip\leftarrowr16/m16

                段间转移,直接寻址:JMP  far ptr lable;ip\leftarrowlabel的偏移地址,cs\leftarrowlabel的段地址

                段间转移,间接寻址:JMP  far ptr mem;ip\leftarrow[mem],cs\leftarrow [mem+2]

        2. 条件转移指令jcc(指令集)

                        JCC  label;条件满足,发送转移,ip\leftarrowip+8位位移量,否则顺序执行ip\leftarrowip+2

                                                                根据标志位状态

                                                              针对无符号数高低的比较 

                                        ​​​​​​​        ​​​​​​​        ​​​​​​​      针对无符号数大小的比较  

循环指令(loop,loope/loopz,jcxz,loopne/loopnz)

        提醒:循环指令不影响标志位。

        loop指令首先将CX值减1,如何判断CX是否为0,CX不为0,则继续执行循环体内的指令;CX为0,表示循环结束,于是程序退出循环,顺序执行后面的程序。

        使用loop的三要点:

        1.必须在CX中存放循环次数;

        2.loop指令的标号一般应在前面,要执行的循环程序段应写在标号和LOOP指令之前 

        3.为防止CX初值为0导致循环次数出错,可以在循环之前使用JCXZ指令进行判断。

子程序指令(call,ret)

                                                            程序调用和返回堆栈示意图

远调用时注意cs先入栈,ip后入栈。ip先赋新值,cs后赋新值 

远调用时注意ip先出栈,cs后出栈 ;

 

二 , 寻址方式:

三类七种

        立即数寻址   eg:mov ax,  0102h

        寄存器寻址   eg:   mov ax, 1234h

        存储器寻址(五种):

                1. 直接寻址: mov ax, [2000h];指令中直接包含有效地址

                2. 寄存器间接寻址:有效地址存放在寄存器中,8086中寄存器只能是基址寄存器BX或者变质寄存器SI,DI。其默认的段地址在DS段寄存器中,可以使用段超越改变前缀。eg:mov ax,[si]

                3. 寄存器相对寻址方式:有效地址是寄存器的内容与有符号8位或16位位移量之和,寄存器可以是BX,BP,SI,DI。操作数的EA = BX/BP/SI/DI+8/16位位移量。BP默认堆栈段SS,其他默认DS

eg:mov ax,[di + 06h]。采用BP相对寻址时如果偏移量为0,也可以不写,形式上与寄存器间接寻址一样。eg:mov ax,[bp]  ; mov ax, [bp+0]

                4. 基址变址寻址: 有效地址EA= BX/BP+SI/DI。BX默认段DS,BP默认段SS。

                5. 相对基址变址寻址:EA = BX/BP+SI/DI+8/18位偏移量。

同一寻址方式可以写成不同形式:

        mov ax, [bx][si] ;也可写成:mov ax ,[bx+si]

        mov ax count[si] ;也可以写成 mov ax, [si+count],count为变量或常量,若为变量此处count取偏移地址地址,而不是取count表示的值。

        mov ax wnum[bx][si];也可写成mov ax, [bx+si+wnum]或者mov ax,wnum[bx+si]

  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值