汇编学习笔记(9)--算术指令

xchg op1,op2;交换指令
操作:temp=op1 op1=op2 op2=temp
格式:xchg reg,reg
xchg reg,mem
xchg mem,reg
xchg不影响任何标志位,xchg的操作数中不可以有段寄存器

in acc,port ;从端口读数据到al或ax中
操作: acc=[port];[port]表示地址为port的端口中的内容
格式:
	in acc,idata;idata是立即数,并且00h<idata《=0ffh,acc为al或ax
	in acc,dx;0000h<dx<=offffh;acc为al或ax
	当acc为al时,in al,port表示从端口port中读取一个字节到al中,当acc为ax时,in ax,port表示先从端口port读取一个字节到al,再从端口port+1中读取另一个字节到ah中
	
	
out port,acc;把al或ax的值写入端口
操作:[port]=acc;
格式:
out idata,acc;idata是立即数,并且00h<=idata<=0ffh;acc为al或ax
out dx,acc;0000h<=dx<=0ffffh;acc为al或ax
如果acc为ax时,表示先把al的值写入端口port中,再把ah的值写入port+1中

lea dest,src;装入有效地址(load effective address)
操作:dest=offset src;offset src表示源操作数src的偏移地址
格式:
lea reg,mem

lds dest,src;把远指针装到ds:dest(load ds and dest with a far pointer)
操作:
dest=word ptr [src];word ptr [src]表示src所指的远指针的偏移地址
ds=word ptr [src+2];src所指的远指针的段地址
格式 :
lds reg.mem;mem为一个double word
远指针就是由段地址与偏移地址两部分构成的地址,一个远指针存放到内存中,偏移地址在前,段地址在后

les dest,src;把远指针装到es:dest(load es and dest with a far pointer)
lahf ;把标志寄存器fl的低8位复制到ah(load ah with flags)
操作:
ah = FL&0FFh; 即获取FL的低八位
格式:lahf

sahf;把ah存入FL的低8位(store ah in flags)
操作:
FL=(FL&0FF00h)|2|(AH&0D5h);2表示FL的第1位也就是(从0开始算)恒为1
;ah&0D5h表示只保留ah的bit7,6,4,2,0
注意FL的bit1,bit3,bit5是不可以改变的,他们的值始终是1,0,0

pushf;把FL压入堆栈
popf;从堆栈弹出FL
;这两个指令不仅可以访问FL的低8位,也可以访问高八位

转换指令

符号扩充指令

cbw;符号扩充字节为字(convert byte to word)
操作: if(AL&80h!=0);若al最高位是1
ah=0ffh
else ah=00h
endif
格式:cbw
使用
cbw就好

cwd;符号扩充字为双字(convert word to double word)
操作:
if(AX&8000h!=0)
dx=0ffffh
else dx=0000h
endif
例如
mov ax,0FFFEh;
cwd ;dx=0FFFFh

xlat;换码(translate)
操作:al=byte ptr ds:[bx+al]
例如
mov ax,1000h
mov ds,ax
mov bx,10F0h;假设1000:10f0->"0123456789ABCDEF"
mov al,10
xlat;AL=ds:[bx+al],10就转化为A
;一般在使用xlat指令之前,应先使ds:bx指向一张表,在本例中指向一张十六禁止字符表,其中地址1000:10f0指向字符'0'.以此类推

加法add inc adc

add dest,src;加法
;dest=dest+src
;两数相加可能产生不正确的结果,称之为溢出
;对于非符号数来说,若两数相加产生进位,cf=1称为非符号数的加法溢出
;对于符号数来说,如果两个正数相加产生负数,或两个负数相加产生正数,则称为符号数的加法溢出,即of=1,而正数与负数相加永不溢出,of=0
7f+1(127+1)=80h(-128),of=1
80h(-128)+ff(-1)=7fh(127),of=1
7f(127)+80(-128)=-1(ff),of=0不溢出


inc op;自增
;op=op+1
mov ax,2
inc ax;ax=3
mov ah,0ffh
inc ah;ah=0
inc byte ptr ds:[10ah0]
inc word ptr es:[bx+si]
;inc 指令不影响cf位

adc dest,src;带进位加add with carry
;操作: dest=dest+src+cf

求2f365h与5e024h的和,结果放到dx:ax中
mov ax,0f365h
mov dx,2;dx:ax位2f365h

add ax,0e024h;低16位相加,ax=0d389h,cf=1
adc dx,5;带近卫家

减法:sub,sbb,dec,neg,cmp

sub dest,src
;操作:dest=dest-src;两个符号数相减可能产生溢出,一个正数减去一个负数产生负数,一个负数减去一个正数产生正数,称为符号数减法溢出,OF=1,而正数减去正数,负数减去负数,永不溢出,OF=0
mov al,7eh;127
mov bl,0ffh;-1
sub al,bl;al=80h(-128)正数减负数位负数,OF=1
mov ax,8000h;-32768
mov bx,1
sub ax,bx;ax=7fffh(+32767) of=1;负数减正数产生正数

sbb dest,src;带借位减
;destt=dest-src-Cf
求127546h与109428h的差,保存在dx:ax
mov ax,7546h
mov dx,12h
sub ax,9428h;两数的低16位相减,ax=0e11eh,cf=1
sbb dx,10h

dec op;减一
;op=op-1
;dec指令不影响cf位

neg op;求补
;op=-op
mov al,1
neg al;al=0ffh
mov dx,9880h
neg dx;dx=6780h,0-9880h=6780h
;对任何非零数求补时,cf=1;只有对0,cf=0

cmp op1,op2
;操作 null=op1-op2
;cmp类似于sub但结果不影响op1,只影响标志位
mov al,2 
mov bl,1
cmp al,bl ;al=2,bl=1,cf=0,zf=0,sf=0,of=0
mov ah,1
cmp ah,2;ah=1,cf=1,zf=0,sf=1,of=0
mov al,7fh
cmp al,80h;al=7fh,cf=1,zf=0,of=1,sf=1
比较两个非符号数大小与比较两个符号数大小依据的标志位是不一样的
对于非符号数a,b
cmp a,b
则有cf=1,a<b;说明a减b产生了借位
zf=1 a=b(此时cf=0)
cf=0且zf=0a>b
跳转相关指令
ja 大于则跳转 cf=0且zf=0
jae 大于等于则跳转,条件cf=0
jb 小于  cf=1
jbe 小于等于 cf=1或zf=1
je 等于 zf=1
jne 不等 zf=0

对于符号数a,b
cmp a,b
则有sf!=of a<b;sf=1且0f=0表示a减去b结果位负数同时没有产生溢出,即结果正确,因此a<b,第二种sf=0,of=1表示a减去b位正数但产生了溢出,即结果不正确,因此应该是a<b
zf=1 a=b,与sf of无关
sf=0f且zf=0 a>b;sf=1,of=1,a<b但结果位错,所以a>b,sf=0,of=0.a>b
mov al,1;al=1
mov bl,0ffh;bl=-1
cmp al,bl;cf=1,zf=0,sf=0,of=0 a>b
mov ax,8000h;ax=-32768
mov bx,1
cmp ax,bx;cf=0,zf=0,sf=0,of=1;a<b
与符号数相关指令
jg 大于 sf=off且zf=0
jge 大于等于 sf=of
jl 效于 sf!=of且zf=0
jle 小于等于 sf!=of
je zf=1

乘法 mul,imul

mul src;非符号数乘法
当src为字节(8) ax=al*src
当src为字(16) ds:ax=ax*src
mov al,10h
mov bl,0ffh
mul bl;ax=al*bl=0ff0h
mov al,2
mov ah,3
mul ah;ax=al*ah=6
mov ax,1234h
mov cx,100h
mul cx;dx:ax=ax*cx
mul byte ptr ds:[10a0h];ax=alI*
mul word ptr [bx];dx:ax=ax*

imul src;符号数乘法
操作类似上面
符号数乘法的被乘数,乘数及积都被看作是符号数,
mov al,0ffh;al=-1
mov cl,0feh;cl=-2
imul cl;ax=2
mov ax,0fffdh;ax=-3
mov si,2;si=2
imul si;dx:ax=-6

除法 div,idiv

div op;非符号数除法
al=ax/op,ah=ax%op;当op为字节(8)
ax=dx:ax/op dx=dx:ax%op ;op为字(16)
mov ax,20;被除数
mov cl,3
div cl;al=20/3=6,ah=20%3=2
mov ax,3400h
mov dx,12h
mov bx,100h
div bx;ax=123400/100h=1234h
;dx=123400h%100h=0

idiv op;符号数除法
符号数除法的被除数,除数,商,余数都被看做是符号数
mov ax,0ffe2h;ax=-30
mov bl,8;
idiv bl;al=ax/bl=-3 ah=-30%8=-6
mov al,0f9h;-7
cbw;ax=0fff9h,-7
mov cl,2
idiv cl;al=ax/cl=-7/2=-3 ah=ax%cl=-7%3=-1

mov ax,0fffbh;ax=-5
cwd;dx:ax=0fffffffbh,-5
mov di,3
idiv ;ax=-5/3=-1 dx=-5%3=-2
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值