彙編語言(王爽版)實驗10 編寫子程序


編寫三個子程序:顯示字符串、解決除法溢出的問題、數值顯示。

1.顯示字符串

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
代碼實現

assume cs:code
	data segment
		db 'Welcome to masm!',0
	data ends
	
	code segment
	start:mov dh,8
		  mov dl,3
		  mov cl,2
		  mov ax,data
		  mov ds,ax
		  mov si,0
		  call show_str
		  
		  mov ax,4c00h
		  int 21h
		  
	show_str:	;顯示字符串的子程序
			push cx
			push si
			
			mov al,0A0h ;每行有80*2=160字節,即0A0h
			dec dh 		;行號在顯存中下標從0開始
			mul dh		;相當於從第(n-1)*0A0h個Byte單元開始
			
			mov bx,ax		;定位好的位置偏移地址存放在bx裏
			mov ax,2		;每個字符佔兩個字節
			dec dl
			mul dl			;定位列號 結果ax中存放的是定位好的列的位置
			add bx,ax		;bx中存放行號與列號的偏移地址
			mov ax,0B800h		;顯存開始的地址
			mov es,ax		;es中存放的是顯存的第0頁(0-7)的起始段地址
			mov di,0		;di表示指向顯存的偏移地址
			mov al,cl		;al存放顏色參數
			mov ch,0		;之後cl放字符,當cl取0時,因爲ch一直爲0,cx=0,跳轉到ok標號處
		
		s:	mov cl,ds:[si]		;ds:[si]指向"Welcome to masm!",0
			jcxz ok
			
			mov es:[bx+di],cl	;偶地址存放字符
			mov es:[bx+di+1],al		;奇地址存放顏色
			
			inc si
			
			add di,2
			
			jmp short s		;無條件跳轉,故只有觸發jcxa跳轉才能離開此循環
			
		ok:	pop si
			pop cx
			
			ret
	code ends
end start

運行結果
在這裏插入圖片描述

2.解決除法溢出的問題

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
代碼實現

assume cs:code,ss:stack
	stack segment
		dw 8 dup(0)
	stack ends
	
	code segment
		start:
			mov ax,4240h
			mov dx,000fh
			mov cx,0ah
			
			mov bx,stack
			mov ss,bx
			mov sp,10h
			
			call divdw
			mov ax,4c00h
			int 21h
		divdw:		;公式:X/N = int(H/N)*65536 + [rem(H/N)*65536+L]/N (高16位除以N+((高16位/N的餘數)作爲高16位,低16位是L)/N的和)
			push ax		;保存低16位數據進棧
			mov ax,dx		;高16位值給ax
			mov dx,0	;置0,如果div除法沒有餘數,但是dx中數據未清0,則會造成影響。
			div cx	;H/N
			mov bx,ax	;ax把運算結果的商給bx,dx的值爲餘數
			
			pop ax		;把棧中低16位的數據再給ax
			div cx		;L/N 16位除法的時候,默認dx爲高16位,ax爲低16位
			mov cx,dx
			mov dx,bx
			
			ret
	code ends
end start	

運行結果
在這裏插入圖片描述

3.數值顯示

在這裏插入圖片描述
在這裏插入圖片描述
代碼實現

assume cs:code
	data segment
		db 10 dup (0)		;存放修改好的字符
	data ends
	
	code segment
	start:
		  mov ax,12666
		  mov bx,data		;ds:si指向字符串的首地址
		  mov ds,bx
		  mov si,0
		  
		  call dtoc		;dtoc子程序實現將word型整數轉化爲ASCII碼字符串並存儲
		  
		  mov dh,8		;初始化打印的位置
		  mov dl,3
		  mov cl,2
		  call show_str
		  
		  mov ax,4c00h
		  int 21h
		  
	dtoc:		;轉換的子程序
			push dx
			push cx
			push ax
			push si
			push bx
			
			mov bx,0	;存放位數
		s1: mov cx,10d	;d表示10進制,作爲除數
			mov dx,0
			div cx		;除以10
			mov cx,ax	;商給cx,餘數在dx
			
			jcxz s2		;商爲0則跳轉到s2
			add  dx,30h
			push dx		;把數據放在棧裏保存
	
			inc bx		;bx+1來到下一位
			jmp short s1
			
			
			
		s2:			;此時已經是最後一個餘數
			add dx,30h 
			push dx
			inc bx 		;再進行一次棧操作(補充當"商爲0而餘數不爲0的情況")
			mov cx,bx	;循環bx次
			mov si,0
			
		s3:
			pop ax	;循環將棧中的數據依次出棧放到指定內存中
			mov [si],al
			inc si
			loop s3
			
		okay:
			pop bx
			pop si
			pop ax
			pop cx
			pop dx

			ret
	show_str:	;顯示字符串的子程序
			push cx
			push si
			
			mov al,0A0h ;每行有80*2=160字節,即0A0h
			dec dh 		;行號在顯存中下標從0開始
			mul dh		;相當於從第(n-1)*0A0h個Byte單元開始
			
			mov bx,ax		;定位好的位置偏移地址存放在bx裏
			mov ax,2		;每個字符佔兩個字節
			dec dl
			mul dl			;定位列號 結果ax中存放的是定位好的列的位置
			add bx,ax		;bx中存放行號與列號的偏移地址
			mov ax,0B800h		;顯存開始的地址
			mov es,ax		;es中存放的是顯存的第0頁(0-7)的起始段地址
			mov di,0		;di表示指向顯存的偏移地址
			mov al,cl		;al存放顏色參數
			mov ch,0		;之後cl放字符,當cl取0時,因爲ch一直爲0,cx=0,跳轉到ok標號處
		
		s:	mov cl,ds:[si]		
			jcxz ok
			
			mov es:[bx+di],cl	;偶地址存放字符
			mov es:[bx+di+1],al		;奇地址存放顏色
			
			inc si
			
			add di,2
			
			jmp short s		;無條件跳轉,故只有觸發jcxa跳轉才能離開此循環
			
		ok:	pop si
			pop cx
			
			ret
	code ends
end start	

運行結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章