获取编译学习笔记 (六)—— si、di,双环

疯狂暑期学习  汇编入门学习笔记 (六)—— 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




原文地址:https://www.cnblogs.com/zfyouxi/p/5040201.html