匯編入門(mén)學(xué)習筆記 (十)—— 標志寄存器、串傳送指令
參考: 《匯編語(yǔ)言》 王爽 第11章
CPU內部有一種特殊的寄存器叫標志寄存器(flag),它與ax,bx,cx等其他寄存器不同,它不是用來(lái)存放數據的,而是用來(lái)存放狀態(tài)的。flag寄存器是按位器作用的,即只有0和1。
flag寄存器的結構:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF SF ZF AF PF CF
在debug中標志位的表示:
標志 1 0
of OV NV
sf NG PL
zf ZR NZ
pf PE PO
cf CY NC
df DN UP
1. ZF標志
零標志位。如果上條相關(guān)指令結果為0,那門(mén)ZF=1,不為0那門(mén)ZF=0
例子:
- movax,1
- subax,1
- movax,1
- andax,0
執行后zf為1
add,sub,mul,div,inc,or,and等這些運算指令會(huì )影響標志寄存器
mov,push,pop等轉移指令對標志寄存器沒(méi)有影響
2. PF 標志
奇偶標志位。是0是1的規則 ,類(lèi)似于奇校驗。
如果上條相關(guān)指令結果二進(jìn)制中1的個(gè)數為偶數,則PF=1,為奇數則PF=0 。
例子:
- moval,1
- addal,10
al = 00001011b
pf = 0
- moval,1
- oral,2
al = 00000011b
pf = 1
3. SF標志
符號標志位。
如果上條相關(guān)指令結果為負數,則SF=1,正數則SF=0
本質(zhì)就是看第一位是否為1
- moval,10000001b
- addal,1
SF = 1
4. CF標志
表示無(wú)符號計算中的進(jìn)位(注意:inc和dec指令是不影響CF的,但會(huì )影響ZF與OF)
例子:
- moval,98H
- addal,al
CF = 1
相減為負數,也會(huì )使得CF = 1
- movax,1
- subax,2
5. OF標志
表示有符號計算的溢出(注意:inc和dec指令是會(huì )影響OF的)
例如8位補碼 表示的數的范圍 -128~127
例子:
- moval,0F0H
- addal,88H
-16+(-120) = -136
超過(guò)了范圍,所以OF = 1
6. abc 指令
帶進(jìn)位的加法指令
abc ax,bx
相當于(ax)=(ax)+(bx)+CF
例子:實(shí)現兩個(gè)128位數據相加
- assumecs:code,ds:data
- datasegment
- db88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h
- db11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h
- dataends
- codesegment
- start:movax,data
- movds,ax
- movsi,0
- movdi,16
- movcx,8
- calladd128
- add128:pushax
- pushcx
- pushsi
- pushdi
- subax,ax;將CF設置為0
- s:movax,[si]
- adcax,[di]
- mov[si],ax
- incsi;不用add是因為add會(huì )改變CF的值
- incsi
- incdi
- incdi
- loops
- popdi
- popsi
- popcx
- popax
- codeends
- endstart
7. sbb指令
sbb是帶借位的減法指令
sbb ax,bx 相當于(ax)=(ax)-(bx)-CF
8. cmp指令
cmp是比較指令,相當于減法,但不保存結果只改變flag
cmp ax,bx
對于無(wú)符號數來(lái)說(shuō)
如果(ax)=(bx) 則(ax)-(bx)=0, 所以:zf = 1;
如果(ax)!=(bx) 則(ax)-(bx)!=0,所以:zf = 0;
如果(ax)< (bx) 則(ax)-(bx)會(huì )產(chǎn)生錯位,所以:cf = 1;
如果(ax)>(bx) 則(ax)-(bx)不會(huì )產(chǎn)生錯位,結果也不可能為0, 所以:cf = 0 并且zf = 0;
可以這么說(shuō):
zf = 1 說(shuō)明(ax)=(bx)
zf = 0 說(shuō)明(ax)!=(bx)
cf = 1 說(shuō)明(ax)< (bx)
cf = 0 說(shuō)明 (ax)>= (bx)
cf = 0 并且zf = 0 ,說(shuō)明(ax)>(bx)
cf = 1 或者zf=1, 說(shuō)明 (ax)<=(bx)
對于有符號數來(lái)說(shuō)
zf = 1 說(shuō)明(ax)=(bx)
zf = 0 說(shuō)明(ax)!=(bx)
sf=1 并且 of=0,說(shuō)明(ax)<(bx)sf=0 并且 of=1,說(shuō)明(ax)<(bx)
sf=1 并且 of=1,說(shuō)明(ax)>(bx)
sf=0 并且 of=0,說(shuō)明(ax)>=(bx)
9. 檢測比較結果的條件轉移指令
對于無(wú)符號數:
je 等于則轉移 zf=1
jne 不等于則轉移 zf=0
jb 低于則轉移 cf=1
jnb 不低于則轉移 cf=0
ja 高于則轉移 cf=0且cf = 0
jna 不高于則轉移 cf=1或zf=1
各個(gè)字母的意思:
j:jmp
e:equal
ne:not equal
b:below
nb:not below
a:above
na:not above
例如實(shí)現:如果(ah)=(bh)則(ah)=(ah)+(ah),否則(ah)=(ah)+(bh)
- cmpah,bh
- jes
- addah,bh
- ddah,ah
例子:計算data段中為8的數的個(gè)數,記錄在ax中
- assumecs:code,ds:data
- datasegment
- db8,11,23,8,2,3,8,8
- dataends
- codesegment
- start:movax,data
- movds,ax
- movsi,0
- movax,0
- movcx,8
- s:cmpbyteptrds:[si],8
- jnenext
- incax
- next:incsi
- loops
- movax,4c00H
- int21H
- codeends
- endstart
10. DF 標志位和串傳送指令
df=0 每次操作后si、di遞增;
df=1 每次操作后si、di遞減;
movsb
功能:將ds:si 指向的內存單元中的字節送入es:di中,然后根據標志寄存器df位的值,將si和di遞增或遞減1
相當于:
(1)((es)*16+(di))=((ds)*16+(si))
(2)df=0則:(si)=(si)+1
(di)=(di)+1
df=1則:(si)=(si)-1
(di)=(di)-1
movsw
功能:于movsb相同,只是是傳送一個(gè)字,然后就是si和di是遞增或遞減2
指令cld,std
cld:將df設置為0
std:將df設置為1
rep指令
功能:根據cx的值重復執行,后面的串指令。
格式:rep movsb
例子:復制data中的Welcome to masm!
- assumecs:code,ds:data
- datasegment
- dbWelcometomasm!
- db16dup(0)
- dataends
- codesegment
- start:movax,data
- movds,ax
- moves,ax
- movdi,16
- movsi,0
- movcx,16
- cld
- repmovsb
- movax,4c00h
- int21h
- codeends
- endstart
11. pushf和popf
pushf的功能是將標志寄存器的值壓棧,而popf是從棧中彈出數據,送入標志寄存器中
評論