4—1Copying Data
movs destination, source
1.Each mov instruction has the form and copies a byte, word, doubleword value from the source operand location to the destination operand location.
2.No mov instrution change any falg.
3.用mov指令需要注意的几点内容:
1.两个操作数都在memory里面
2.两个操作数不同大小
3.any mov to or from flag register
4.any mov to the instruction pointer register
5.立即数到段寄存器
6.段寄存器之间的mov
以上都属于不合法的mov指令操作。
下面给一个有关mov指令应用的小例子:
mov eax, source
mov dest, eax
mov eax,source+4
mov dest+4,eax
mov eax,source+8
mov dest+8,eax
例子很简单,就是复制以source为首的空间里的三个doubleword到以dest为首地址的空间去。举这个例子的目的其实是为了介绍source+4,dest+4这么个情况,它实际上指的是the location 4 bytes after the address of source/dest.
xchg destination,source
It's a very useful instruction that exchanges data in one location with data in another instruction.这个指令确实是蛮有效的,因为学过高级语言的都知道,这么个事要三条指令才能完成呢!然后它要注意的地方就是操作数不能都是memory的,其他的书上木有讲,不过猜测应该跟mov一样的。
4—2Integer Addition and Subtraction Instructions
先把指令都罗列出来吧!
add destination, source 加法
sub destination, source 减法
inc destination 加1
dec destination 减1
neg destination 这个定义搞得我蛮晕的,我自己的理解就是“按位求反最后加1”,这样之后的结果就是“正变负,负变正,0还是0”
其实都蛮简单的,就是根据前面的助记符得到意思,然后进行相应的操作,把结果放到目的操作数里面。然后还比较重点的就是这些操作对标志位的影响。干脆点说inc,dec不会影响任何flag;neg的话,我们会侧重的应该就是SF,ZF;add,sub指令就关注CF,OF,SF,ZF。SF,ZF在我看来实在是可简单的所以木有说的必要了。关键就是CF和OF,让我纠结了快一个学期才理解。那具体怎么弄的呢?简单地说用两种方法判断好了。
1.基础方法:CF判断:符号位向外发生借位或者进位的话,carry=1;OF判断:向符号位有进位,符号位向外有进位二者有且只有其中一个发生的,则OF=1。
2.观察法:通过观察两个操作数的正负情况来初步判断进位或者OVERFLOW发生的可能性。
------The length of time takes to execute is measured in clock cycles.具体时间要根据处理器的时钟速度来计算。比如说,你的PC机clock speed是200MHZ,那么每个时钟周期就是5ns,然后用它乘以指令所需要的时钟周期数就得到执行该指令的时间了。
------In general, an instruction may have one of three effects:
1.no flags are altered
2.specific falgs are given values depend on the results of the instrution
3.some flags may be altered, but their settings cannot be predicted
------对于较大数的加减法我们采取的办法是:采用带进/借位的加减法,即adc和sbb。为此我们引入三条新的指令来设置CF的值,分别是clc(置0),stc(置1),cmc(CF=1,则CF=0;CF=1;则CF=0)。
4—3Multiplication Instructions
这一节的指令就两个,mul指令和imul指令,前者是针对无符号书的,后者则是有符号数,它们的结果也相应的为无、有符号数,mul指令比imul指令稍快一些。先看mul指令吧,因为它相对来说简单点。
mul source
这条指令只有一个操作数,可以是byte,word或者doubleword,然后可以在register或memory中。你可能会想,乘法怎么可能只有一个操作数呢?下面就是揭开真想的时候了!人家把被乘数默认放到AL,AX和EAX中了,分别对应上面的byte,word和doubleword。然后如果是byte乘以byte的话,结果为16位放到AX中;word*word呢,结果为32位,高16位放到DX中,低16位放到AX中;doubleword*doubleword时,结果就是64位,高32位放到EDX,低32位放到EAX中。源操作数不变。mul指令对标志位的影响对我们来说有意义的是:如果high order half 不为0,那么CF=1,OF=1;如果high order half 为0,那么CF=0,OF=0。其他的一些比如说AF, PF, ZF之类的也有可能被改变,我们就不予以考虑了。
接着来看imul指令,它有三种形式:
imul source
imul register, source
imul register, source, immediate
a.第一种和mul指令的效果完全一致。b.第二种的话,目的操作数是在register里面的,源操作数的话,既可以是在register里的,又可以在memory里的,还可以是立即数,是立即数的话有一点特殊,它可以是byte或者跟目的操作数一致。然后还有一点要注意:操作数只能同时为words或者doublewords,与前面不矛盾的,因为你立即数为immediate byte的话,我也要先进行标志位扩展之后再拿来运算的。最后结果放到目的操作数register里面,细心一点的话应该能发现点什么,什么呢?结果可能太大而放不进去对吧?前面我们考虑的都是提前做好准备,预留足够的地方来装结果的。那现在我们要使所得结果有意义的话只好依赖于CF和OF了,如果超出了register范围的话,CF、OF设为1,结果无意义;否则为0,结果有意义。c.最后一条指令的话,register做目的地,放结果用的,被乘数和乘数一个在source(可为register或者memory)里,一个是立即数。然后的话,register 和 memory大小必须一致,需同时为16位或者32位。对CF、OF的影响同第二条imul指令。
讲完了所有的指令我们会发现一件有趣的事情,就是结果只能放在register里面。
4—4Division Instructions
把乘法指令搞清楚了,除法指令就简单了!就两种形式:
div source (for unsigned numbers)
idiv source (for signed numbers)
这里源操作数唯独不能为立即数,然后目的操作数或则说被除数默认的被放到AX,DX:AX, EDX:EAX中,具体哪一个又由source决定(联系乘法指令一想就明白了)。然后为了操作方便,80x86又为我们提供了一些扩展指令,它们是cbw,cwd,cdq。它们进行的是符号位扩展,对应默认操作数AL,AX,EAX,结果分别放到
AX,DX:AX,EDX:EAX。完了还有一些其他的扩展指令,比如cwde,它做的是对AX进行符号位扩展,结果放到EAX;还有movsx,movzx,它们就是分别把对应的源操作数(in register or memory,只能是8位或者16位)往high order half添0或添1放到是源操作数一倍大小的register中。所有的扩展指令都不影响flag值,任何的。最后说下除法指令得到的结果在目的操作数里的放法以及对标志位的影响。对于doubleword的除数,商放在EAX中,余数放在EDX中;对于word的除数,商放在AX中,余数在DX中;对于byte的除数,商放在AL中,余数在AH中。稍总结一下就是商放在low half order。关于affecting flags英文写的经典,直接贴了:The division instructions do not set flags to any significant values.They may destroy previously set values of AF, CF, OF, PF, SF, and ZF flags.
重点的基本就这么多了!