彙編語言(王爽)實驗十

實驗十

編寫3個子程序

1、顯示字符串

功能:在指定的位置,用指定的顏色,顯示一個用0結束的字符串

參數:(dh)=行號、(dl)=列號、(cl)=顏色、ds:si指向字符串的首地址

行、列從0開始計數

如要求在屏幕的8行3列,用綠色顯示data段中的字符串

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:	mov ax,0B800H			; 確定輸入字符串的段地址
 			mov es,ax
 			
 			mov al,00A0H			; 每行差00A0個字節,不能字母開頭
 			mul dh					; 計算出的"行偏移地址"存在ax中
 			push ax					; 入棧,暫存
 			
 			mov al,2				; 每一列佔兩個字節,第2個字節
 			mul dl					; 計算出的"列偏移地址"存在ax中
 			
 			pop di					; 取出之前的"行偏移"
 			add di,ax				; "行偏移"+"列偏移"=總的偏移地址
 			
 	input:	push cx					; jczx要用到cx,會影響顏色的輸入
	 		mov cx,[si]				; 從data中取字符
 			jcxz end_input			; 若取到末尾,跳轉
 			mov es:[di],cx			
 			inc si					; 指向下一個字符
 		   	inc di					
 		   	pop cx
 			mov es:[di],cl			; 存入顏色信息
 			inc di
 			jmp short input
 			
end_input:	pop cx					; 在到了字符串末尾之後,
									; 之前的cx還在棧中,要出棧
									; 否則ret從棧中取出原來的IP值時會出錯
			ret
			
code ends
end start

在這裏插入圖片描述

2. 解決除法溢出問題

功能:進行不會產生溢出的除法運算,被除數爲dword,除數爲word,結果爲dword

參數:(ax)=dword型數據的低16位

​ (dx)=dword型數據的高16位

​ (cx)=除數

返回:(dx)=結果的高16位

​ (ax)=結果的低16位

​ (cx)=餘數

思路:對於32位的被除數,先高位的16位在前面補0組成一個32位數除以除數,得到的商便是最終結果的高16位,而得到的餘數作爲一個新的32位數的高16位,而被除數的低16位作爲新32位數中的低16位,除以被除數,得到的餘數就是最終的餘數,而得到的商就是結果的低16位

assume cs:code

code segment
	start:	mov ax,4240H
			mov dx,000FH
			mov cx,0AH
			call divdw
			
			mov ax,4c00h
			int 21h
			
	divdw:	push ax			; 先高位除以被除數,暫存ax
			mov ax,dx		
			mov dx,0		; 除數是16位,被除數應該爲32位,高位存儲在dx中
			div cx
			mov bx,ax		; 用bx存儲ax,即商
		
        	pop ax			; 彈出低位的值
			div cx			; 此時,第一次除法運算得到的餘數作爲高16位的值
							; 存儲在在dx中
			mov cx,dx
			mov dx,bx
			
			ret
code ends
end start

在這裏插入圖片描述

3.數值顯示

把數據如12666以十進制顯示在屏幕上

思路:12666每次除以10取餘,數字加30H就是對應的字符的ASCII碼值(字符“0”~“9”對應的ASCII碼是30H-39H),將數據轉換爲字符串,然後調用show_str顯示在屏幕上

assume cs:code

data segment
	db 10 dup (0)
data ends

code segment
	start:	mov ax,12666
			mov bx,data
			mov ds,bx
			mov si,0
			call dtoc

			mov dh,8
			mov dl,3
			mov cl,2
			call show_str

			mov ax,4c00h
			int 21h
			
	 dtoc:	mov bx,10			; 除數
	 		mov dx,0			; dx爲32位被除數的高16位
			div bx
			inc si				; 記錄數的長度
			mov cx,ax			; 把商賦值給cx,用於jcxz
			push dx				; 判斷前先把餘數入棧
			jcxz ok
			jmp short dtoc

	   ok:	mov cx,si			; 數的長度就是循環的次數
	   		mov si,0			; si爲data段的偏移地址
	    s:	pop bx
			add bx,30H			; 數字的大小+30H就是對應字符的
								; ASCII碼
			mov [si],bl			; 存儲那些ASCII碼只需一個字節
			inc si
			loop s

			mov [si],cl			; 由於show_str使用時
								; 默認字符串以0結尾,因此在最後補0
			mov si,0			; 修改爲0保證show_str的正確執行

			ret

show_str:	mov ax,0B800H			; 確定輸入字符串的段地址
 			mov es,ax
 			
 			mov al,00A0H			; 每行差00A0個字節,不能字母開頭
 			mul dh					; 計算出的"行偏移地址"存在ax中
 			push ax					; 入棧,暫存
 			
 			mov al,2				; 每一列佔兩個字節,第2個字節
 			mul dl					; 計算出的"列偏移地址"存在ax中
 			
 			pop di					; 取出之前的"行偏移"
 			add di,ax				; "行偏移"+"列偏移"=總的偏移地址
 			
 	input:	push cx					; jczx要用到cx,會影響顏色的輸入
	 		mov cx,[si]				; 從data中取字符
 			jcxz end_input			; 若取到末尾,跳轉
 			mov es:[di],cx			
 			inc si					; 指向下一個字符
 		   	inc di					
 		   	pop cx
 			mov es:[di],cl			; 存入顏色信息
 			inc di
 			jmp short input
 			
end_input:	pop cx					; 在到了字符串末尾之後,
									; 之前的cx還在棧中,要出棧
									; 否則ret從棧中取出原來的IP值時會出錯
			ret


code ends
end start

在這裏插入圖片描述

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