匯編入門(mén)學(xué)習(xí)筆記 (六)—— si、di,雙重循環(huán)
參考: 《匯編語(yǔ)言》 王爽 第7章
1. and和or指令,與[bx+idata]
and和or,就不多說(shuō)了。
[bx+idata] 這樣寫(xiě)是可以的,某些情況下,比較方便。
[bx+idata] 也可以寫(xiě)成 idata[bx]
直接見(jiàn)例子: 把’ABcde‘ 跟 ‘fGHig’ 都改成大寫(xiě)(ASCII中大寫(xiě)字母與小寫(xiě)字母二進(jìn)制中,只有第五位不同,大寫(xiě)字母是0,小寫(xiě)字母是1)
- assumecs:code,ds:data
- datasegment
- dbABcde
- dbfGHIg
- dataends
- codesegment
- start:movax,data
- movds,ax
- movbx,0
- movcx,4
- moval,00100000b
- s:or[bx],al
- or[5+bx],al;[5+bx]也可以寫(xiě)成5[bx]
- incbx
- loops
- movax,4c00H
- int21H
- codeends
- endstart
2. si,di,與[bx+si],[bx+di],[bx+si+idata],[bx+di+idata]
si與di,除了不能像bx一樣分成bh,bl,其他與bx一樣。如 mov ax,[si] 等等
[bx+si],[bx+di],[bx+si+idata],[bx+idata]
這些都是可以的,某些情況下,比較方便。
其中[bx+si]與[bx+di] 可以寫(xiě)成 [bx][si],[bx][di]
[bx+si+idata],[bx+di+idata]可以寫(xiě)成idata[bx][si],idata[bx][di]
例子:復(fù)制Welcome!
- assumecs:code,ds:data
- datasegment
- dbWelcome!
- dataends
- codesegment
- start:movax,data
- movds,ax
- movsi,0
- movcx,4
- s:movax,[si]
- mov8[si],ax
- addsi,2
- loops
- movax,4c00H
- int21H
- codeends
- endstart
例子:將data中的單詞的首字母改成大寫(xiě)
- assumecs:code,ds:data
- datasegment
- db1.file
- db2.edit
- db3.search
- db4.view
- dataends
- codesegment
- start:movax,data
- movds,ax
- movbx,0
- movcx,4
- moval,11011111b
- s:and[bx+2],al
- addbx,8
- loops
- movax,4c00H
- int21H
- codeends
- endstart
3. 雙重循環(huán)
例子:data中單詞改成大寫(xiě)的
- assumecs:code,ds:data
- datasegment
- dbibm
- dbdec
- dbdos
- dbvax
- dataends
- codesegment
- start:movax,data
- movds,ax
- movbx,0
- moval,11011111b
- movcx,4
- s:movcx,3
- movsi,0
- s0:and[bx+si],al
- incsi
- loops0
- addbx,8
- loops
- movax,4c00H
- int21H
- codeends
- endstart
上面 的代碼,是錯(cuò)誤的會(huì)出現(xiàn)是死循環(huán)。因?yàn)閏x不斷的被賦予3,導(dǎo)致外層循環(huán)死循環(huán)。
- assumecs:code,ds:data
- datasegment
- dbibm
- dbdec
- dbdos
- dbvax
- dataends
- codesegment
- start:movax,data
- movds,ax
- movbx,0
- moval,11011111b
- movcx,4
- s:movdx,cx;dx用來(lái)臨時(shí)存放外層的cx的值
- movcx,3
- movsi,0
- s0:and[bx+si],al
- incsi
- loops0
- movcx,dx;用來(lái)回復(fù)外層循環(huán)的cx
- addbx,8
- loops
- movax,4c00H
- int21H
- codeends
- endstart
上面的代碼,雖然能解決上面問(wèn)題,能正常運(yùn)行。但是寄存器的數(shù)量有限,有時(shí),可能沒(méi)有其他的寄存器可以用。
解決方法,保存在內(nèi)存中。例子:
- assumecs:code,ds:data
- datasegment
- dbibm
- dbdec
- dbdos
- dbvax
- dw0;定義一個(gè)字,用來(lái)保存cx
- dataends
- codesegment
- start:movax,data
- movds,ax
- movbx,0
- moval,11011111b
- movcx,4
- s:movds:[20H],cx
- movcx,3
- movsi,0
- s0:and[bx+si],al
- incsi
- loops0
- movcx,ds:[20H]
- addbx,8
- loops
- movax,4c00H
- int21H
- codeends
- endstart
上面的代碼,解決了寄存器不夠的情況。但是,還是比較復(fù)雜,如果有很多循環(huán),就會(huì)弄不清楚。
解決方法,使用棧來(lái)保存恢復(fù)cx。例子1:
- assumecs:code,ds:data,ss:stack
- datasegment
- dbibm
- dbdec
- dbdos
- dbvax
- dataends
- stacksegment
- dw0,0,0,0,0,0,0,0
- stackends
- codesegment
- start:movax,data
- movds,ax
- movax,stack
- movss,ax
- movsp,16
- movbx,0
- moval,11011111b
- movcx,4
- s:pushcx
- movcx,3
- movsi,0
- s0:and[bx+si],al
- incsi
- loops0
- popcx
- addbx,8
- loops
- movax,4c00H
- int21H
- codeends
- endstart
例子2:把data中的單詞,前3個(gè)字母改成大寫(xiě)
- assumecs:code,ds:data,ss:stack
- datasegment
- db1.display.......
- db2.brows.........
- db3.replace.......
- db4.modify........
- dataends
- stacksegment
- dw0,0,0,0,0,0,0,0
- stackends
- codesegment
- start:movax,data
- movds,ax
- movax,stack
- movss,ax
- movsp,16
- movbx,0
- moval,11011111b
- movcx,4
- s:pushcx
- movsi,0
- movcx,3
- s0:and[bx+si+2],al
- incsi
- loops0
- popcx
- addbx,10H
- loops
- movax,4c00H
- int21H
- codeends
- endstart
評(píng)論