8086的指令系统

今天上午综测答辩结束,感觉就很一般,但是我昨晚也操心到觉都有点没睡好,今天中午舍友玩P5吵得我也没睡着,感觉脑袋昏昏沉沉,汇编上课没认真听讲,晚上来补一补。还是采用写一些讲解PPT,补充一些个人看法的方式,由于是复习自用的,所以思路可能很跳。

首先,8086指令系统有以下六种:

我不知道为什么?新版QQ截图的时候老是屏幕变黑或者变灰。

一、数据传送类指令

通用数据传送类指令

1、传送指令MOV:

mov  dest,src;    dest<-src

这个就是把src传给dest.

其中有很多形式:

mov   reg/mem, imm;        立即数送寄存器或主存

mov   reg/mem/seg , reg;  寄存器送寄存器(包括段寄存器)或主存

mov   reg/seg, mem;          主存送寄存器(包括段寄存器)

看这上面的注意点:两个段寄存器之间不能直接传数据,并且立即数不能直接送入段寄存器里面。

PPT上标红的是错误的汇编语法,其实上面的mov dl,ax和mov [1000H],[2000H]也是错误的。为什么?

mov dl,ax错是因为ax是16位dl是8位放不下,mov [1000H],[2000H]错是因为8086不支持内存空间转移到内存空间。假如你要做内存空间转移的操作,可以选择用寄存器做中介。

mov ax,buffer1

mov buffer2,ax   这是书上给出的例子。

关于为什么立即数不能直接送入段寄存器里面,据说是因为立即数直接写入段寄存器这样的指令,被翻译成机器码之后将占用更多的字节,在事先规定的指令长度范围内无法存贮下这么多的内容,因此改由先写入通用寄存器,再由通用寄存器写入段寄存器的办法代替。我们要记住这就是8086的设计。

这里插播一个知识点:以字母打头的立即数前面要加一个前导0.原因不想打字了。

另外mov中还有byte和word这2个关键字,其实8086是16位微处理器,所以word就是16位,byte是8位。观察这个指令:

mov  al, 050ahl;   这肯定是非法指令啊!050ah是字,al是字节,是装不下的。

2、交换指令XCHG:

这是老师的PPT,但是我觉得有点小问题:

问题出在  XCHG  mem,mem  的形式是非法的。

XCHG指令可以在通用寄存器与通用寄存器或存储器之间对换数据,但是不能在存储器与存储器之间交换数据。

这是给出的注意点,上面也提到不能同时位mem.

XCHG怎么记住呢?我们知道对换是exchange,这里取xchg,我猜的,就这样记吧。

3、换码指令XLAT

这个是老师课上讲的最抽象的。当时我确实没听,开摆了。

xlat的作用是将BX指定的缓冲区中,AL指定的位移处的数据取出来赋给AL。

现在我感觉就是一种查表。

这里等价于把AH设置为0(AL不受影响),所以BX加上AX就是相当于BX位移了AL的距离,然后把现在的BX内存中的值给AL。有没有感觉像是数组:

A【n】,你的BX就是数组头指针A,然后AL就是n呀。所以这是一种查表时候用的命令。

PPT的例二没看懂,不想说了。

堆栈操作类指令

堆栈感觉不用多说,毕竟这个数据结构挺常见,有没有做过判断有效括号的题、有没有做过单调栈问题,这玩意有时也很有难度。

1、进栈指令PUSH

有一点还是要注意一下的:

比如push   【2000h】是什么意思?

千万别说是将主存2000h地址内存的数据压栈。

应该是DS:【2000h】.这才是正确的。

另外要记住一点,进栈的话SP是减2。

2、出栈指令POP

标志寄存器传送指令

这个东西我不知道重不重要,我只记得老师讲这里的时候我根本就没听,当时感觉啥都听不进去了。

我觉得要理解这里首先要复习一下标志寄存器:

标志寄存器里面有一堆标志位(雾)

LAHF就是把标志寄存器低8位填到AH里面。

这里还有7个标志处理指令,单独拿出来也是一条汇编语句。

这个sti是开中断,cli是关中断。这个在操作系统实验课的代码中操作过。其他的也类似,反正都是一些对标志状态寄存器的操作,也不知道会怎么考。毕竟我现在只关注这个,开始混日子了。

地址传送指令

地址传送指令将存储器的逻辑地址送至指定的寄存器。

这个LEA就是传有效地址,

平时我们看到

mov  bx,[bx+si+0f62h]这个意思是把这个地址内存单元里面的数移到bx里面

但是

lea  bx,[bx+si+0f62h]是把这个有效地址给BX。

我觉得他等价于 mov bx,bx+si+0f62h;

所以为什么不直接用mov bx,bx+si+0f62h;非要lea  bx,[bx+si+0f62h]。这样还多出一个LEA指令码,让我觉得很匪夷所思,到底是谁脑子有问题?是我吗?

还有个LDS指令和LES指令我有点看不懂。

8086具有20条地址总线,这使得8086能够直接寻址的最大内存空间为2^20(即1MB)字节,地址范围从00000H到FFFFFH。

为啥Mem32能窜出32位,这个有点搞笑了,有没有懂得小伙伴能在评论区给我说一下。

今天就更到数据传送类搞完。明天写算术运算指令,那个好像很难。

---------------------------------------------------------------------------------------------------------------------------------

好,我们接着更新(9.25),合肥刚刚地震了啊,但是我没啥感觉,还不如上个星期那次起码感觉被晃了一下。地震以后综测结果也出来了,排序没变化,就是差0.3分进果酱评选,可惜了。

二、算术运算指令

加法指令

1、ADD指令

2、ADC指令

这里可能有一些小伙伴分不清ADD指令和ADC指令啊。

实际上这里有个多字节数相加的例子:

第一个数字是          DX  AX   0002 F365

第二个数字是          BX  CX   0005 E024

由于这些数字是多字节数,超过了通用寄存器的16位,所以用两个寄存器组合表示

对于多字节数的低位部分相加,可以用ADD,进位的CF会置为1,这里F+E肯定进位了。

高位部分相加,就要用ADC指令,把低位部分的CF寄存器也加上。

ADC指令就是DST+SRC+CF,而ADD指令是DST+SRC,不会加CF的。

3、INC指令

CF是进位标志  OF是溢出标志  SF是符号标志  ZF是零状态标志  别忘记啦

减法指令

1、SUB指令

2、SBB指令

就和ADD和ADC类似,SUB和SBB的区别在于一个不会减CF一个会减。

第一个数字是          DX  AX   0005 0001

第二个数字是          BX  CX   0005 0002

AX-CX后变成0FFFFH,CF为1.

SBB命令是用于高位部分相减的,执行的是DX-BX-CF。

3、DEC指令

4、NEG指令

NEG指令用于计算一个数的补数,即取反加一。它将目标操作数的值变为其相反数,同时设置标志位。比如,NEG AX会将AX寄存器中的值变为其相反数,影响溢出和零标志。

在计算减法时,NEG指令常被用来简化操作。具体来说,减法 A−B可以转换为加法 A+(−B)。这里的-B可以通过NEG指令来实现。

示例

假设我们要计算 AX-BX,可以用NEG指令来完成:

MOV AX, 10  ; AX = 10
MOV BX, 3   ; BX = 3
NEG BX      ; BX = -3
ADD AX, BX  ; AX = 10 + (-3) = 7

这样,通过NEG和ADD指令组合,可以实现减法的计算。

优点

  • 简化代码:使用NEG可以减少直接的减法指令,尤其是在某些需要多次使用同一减数的情况下。
  • 统一操作:在处理一些算法时,使用加法和取反的方式可能更容易理解和实现。

GPT说得这个简化代码给我逗乐了,

NEG BX      ; BX = -3
ADD AX, BX  ; AX = 10 + (-3) = 7

按理说可以替换为

SUB AX,BX

这还叫简化??

5、CMP指令

例3

这个例3很有意思,是对于加减法汇编指令的一个阶段性总结。

张老师说不看答案你们肯定写不出来。

x、y、z均为双精度无符号数,分别存放在地址为X, X+2;Y, Y+2;Z, Z+2的存储单元中,用指令序列实现 w<-x+y+24-z ,并用W, W+2单元存放w。

要实现x+y,因为他们都是双精度的,都要用两个通用寄存器存储。

先让低位部分相加,也就是X+Y。然后让高位部分相加,注意高位部分要用ADC,(X+2)+(Y+2)。

再加立即数24.直接把24ADD到低位上,也就是CX寄存器,然后一步很重要

ADC BX,0  这一步是在说24加低位上有可能进位,所以ADC一个0的实际目的是给BX加上可能存在的进位CF。这一步我估计就是张老师说你们写不出来的原因,因为大部分人初学的时候会忽略掉这一步。

SUB CX,Z;

SBB BX,Z+2。就是类似上面说过的多字节数相减,低位SUB,高位SBB。

最后要把低位的CX传给W,高位的BX传给W+2。

乘除指令

乘除指令实际上有隐含的操作数,AX和DX, 而源操作数则显式的给出。

若是MUL 字节量,就是AL和给出的字节量相乘,乘完得到16位的结果存入AX中。 

若是MUL  字,就是AX去和给出的相乘,乘完以后会得到32位的结果。高字存DX,低字存AX。

IMUL就是看作有符号数的乘法。

上面这个例子中IMUL BL:由于A5是视作有符号数,所以要要到真值,相乘以后再转回补码。

A5 == 1010 0101   看作有符号数的话转为真值就是5B.  就是-91.

-91*17 == -1547 == -060B ==> F9F5

除法指令的话就是、如果是字节除法,AX除以给出的数,8位商存入AL,8位余数存入AH

字除法的话,(DX,AX)除以16位的数,16位商存入AX,16位余数存入DX

扩展指令

从一个例子说起:

你看你想用BL除以CL(无符号数)。正常来说指令就三句话

MOV AL,BL;   先把BL中的除数放到隐含操作数的寄存器AL里面。

MOV AH,0;      给AX高位补齐。

DIV  CL;       再用AX除以CL。

但是如果是有符号数,当你把BL移进AL里面的时候,你不知道BL是正是负。

所以你想把AX的高位补齐的时候就不知道是要全补1(负数)还是全补0(正数)。

所以引入一个新的指令:

最后来看一下一个算术运算指令的综合例子:

这个例子也是有点难度的,我第一次尝试自己写一下发现写到中间没思路了。

在分析完答案后我发现学汇编有一点很重要就是“一些指令它有隐含的操作数,它是固定对某个寄存器执行的”,你在IMUL  Y以后,那个32位的结果在DX:AX里面,后面为啥要把结果的低位AX移到CX里面,把结果的高位DX移到BX里面。然后再把要加的Z移到AX里面。

很简单,只有一个理由就是CWD指令的效果,它是AX->(DX,AX)。

想要x*y+z,你要把Z扩展到32位。你要把原来在AX里面的结果移出来,让Z进去后才能扩展。

后面V也用了一次CWD扩展指令,还复习了SBB\SUB\ADD\ADC,这个可以说是很好的一个例子了。

三、逻辑运算和移位指令

逻辑运算指令

这个我感觉确实没什么好说的,看下面这个例子,他们的作用很清楚:

移位指令

我觉得PPT这图没标注哪个是哪个还挺搞人心态的。我个人分辨就有点难,我计组没学好。

应该是逻辑、算数、循环、带进位循环依次一个一行。

逻辑移位

  • SHL (Shift Left):将所有位向左移动,右侧用零填充。例如,1010 SHL 1 变为 0100
  • SHR (Shift Right):将所有位向右移动,左侧用零填充。例如,1010 SHR 1 变为 0101

算术移位

  • SAL (Shift Arithmetic Left):与 SHL 相同,左移时填充零。
  • SAR (Shift Arithmetic Right):右移时保持符号位不变(即最高位)。例如,对于 1110 SAR 1,结果仍为 1111

循环移位

  • ROL (Rotate Left):将位循环向左移动,左侧的位移到右侧。例如,1010 ROL 1 变为 0101
  • ROR (Rotate Right):将位循环向右移动,右侧的位移到左侧。例如,1010 ROR 1 变为 0101

带进位的循环移位

  • RCL (Rotate through Carry Left):将位向左循环移位,同时将进位寄存器的内容也包含在内。左移时,进位位移到最低位。
  • RCR (Rotate through Carry Right):将位向右循环移位,进位也被包含在内。右移时,进位位移到最高位。

关于这个我还问了一下GPT,GPT说是用两次RCL,但是PPT是SHL AX,RCL DX。

这两个达到的同一种效果,第一个可能比较简单看懂,ROL BL  4位。这一步将BX里面的8位循环移动4位,所以懂得都懂。

第二个是先把BL移动到DL里面,然后算数右移BL(这个实际上是把BX中的BH移到BL)

算数左移DL(实际上是把刚刚移入DX中的BL移到DH的位置)

最后或运算 BX(00H+原来数的低位)和DX(原来数的高位+00H),得到互换后的结果,我觉得这里最后应该是OR BX.DX。

行,后面的还没学到,我先不往下写(9.26)。因为学过以后过PPT速度会更快一点,虽然上课不听,但是还是会有印象的。

---------------------------------------------------------------------------------------------------------------------------------

四、控制转移指令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值