疯狂暑期学习 汇编入门学习笔记 (六)—— si、di,双重循环
參考: 《汇编语言》 王爽 第7章
1. and和or指令,与[bx+idata]
and和or。就不多说了。
[bx+idata] 这样写是能够的,某些情况下,比較方便。
[bx+idata] 也能够写成 idata[bx]
直接见样例: 把’ABcde‘ 跟 ‘fGHig’ 都改成大写(ASCII中大写字母与小写字母二进制中。仅仅有第五位不同,大写字母是0,小写字母是1)
assume cs:code,ds:data data segment db 'ABcde' db 'fGHIg' data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov cx,4 mov al,00100000b s: or [bx],al or [5+bx],al ;[5+bx]也能够写成5[bx] inc bx loop s mov ax,4c00H int 21H code ends end start
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] 能够写成 [bx][si],[bx][di]
[bx+si+idata],[bx+di+idata] 能够写成idata[bx][si],idata[bx][di]
样例:复制Welcome!
assume cs:code,ds:data data segment db 'Welcome! ' data ends code segment start: mov ax,data mov ds,ax mov si,0 mov cx,4 s: mov ax,[si] mov 8[si],ax add si,2 loop s mov ax,4c00H int 21H code ends end start
样例:将data中的单词的首字母改成大写
assume cs:code,ds:data data segment db '1.file ' db '2.edit ' db '3.search' db '4.view ' data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov cx,4 mov al,11011111b s: and [bx+2],al add bx,8 loop s mov ax,4c00H int 21H code ends end start
3. 双重循环
样例:data中单词改成大写的
assume cs:code,ds:data data segment db 'ibm ' db 'dec ' db 'dos ' db 'vax ' data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov al,11011111b mov cx,4 s: mov cx,3 mov si,0 s0: and [bx+si],al inc si loop s0 add bx,8 loop s mov ax,4c00H int 21H code ends end start
上面 的代码。是错误的会出现是死循环。由于cx不断的被赋予3。导致外层循环死循环。
改进,在进行内层循环时把cx保存起来,内存循环结束时,恢复cx。
样例:
assume cs:code,ds:data data segment db 'ibm ' db 'dec ' db 'dos ' db 'vax ' data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov al,11011111b mov cx,4 s: mov dx,cx ;dx用来暂时存放外层的cx的值 mov cx,3 mov si,0 s0: and [bx+si],al inc si loop s0 mov cx,dx ;用来回复外层循环的cx add bx,8 loop s mov ax,4c00H int 21H code ends end start
上面的代码,尽管能解决上面问题,能正常执行。
可是寄存器的数量有限,有时。可能没有其它的寄存器能够用。
解决方法,保存在内存中。
样例:
assume cs:code,ds:data data segment db 'ibm ' db 'dec ' db 'dos ' db 'vax ' dw 0 ;定义一个字,用来保存cx data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov al,11011111b mov cx,4 s: mov ds:[20H],cx mov cx,3 mov si,0 s0: and [bx+si],al inc si loop s0 mov cx,ds:[20H] add bx,8 loop s mov ax,4c00H int 21H code ends end start
上面的代码,攻克了寄存器不够的情况。可是,还是比較复杂。假设有非常多循环,就会弄不清楚。
解决方法,使用栈来保存恢复cx。
样例1:
assume cs:code,ds:data,ss:stack data segment db 'ibm ' db 'dec ' db 'dos ' db 'vax ' data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends code segment start: mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,16 mov bx,0 mov al,11011111b mov cx,4 s: push cx mov cx,3 mov si,0 s0: and [bx+si],al inc si loop s0 pop cx add bx,8 loop s mov ax,4c00H int 21H code ends end start
样例2:把data中的单词,前3个字母改成大写
assume cs:code,ds:data,ss:stack data segment db '1.display.......' db '2.brows.........' db '3.replace.......' db '4.modify........' data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends code segment start: mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,16 mov bx,0 mov al,11011111b mov cx,4 s: push cx mov si,0 mov cx,3 s0: and [bx+si+2],al inc si loop s0 pop cx add bx,10H loop s mov ax,4c00H int 21H code ends end start