匯編語言:實驗十 編寫子程序


實驗10 編寫子程序

這次實驗需要編寫三個子程序,通過它們來認識幾個常見的問題和掌握解決這些問題的方法。

1.顯示字符串

問題

在這里插入圖片描述

子程序描述

在這里插入圖片描述

提示

在這里插入圖片描述

Solution

跟之前的文章的風格相似,都是用王爽老師原書中的描述,在完成第一個程序之前,需要稍微了解一下顯存相關的內容:匯編語言:實驗九 根據材料編程
了解了顯存相關的知識,可以動手操作操作了,題目需要將字符串顯示在特定的行列,如果學習過數據結構或者對二維數組較為了解,求解二維數組中R行C列的元素前面一共有多少個元素?一定知道這么一個計算方法:(R * nums + C),nums表示每一行元素的個數。
在這里插入圖片描述

顯存內存的分布也可以類比成二維數組,每一行一共有 80 個元素,每個元素占用 2 個字節,那么每一行占用了80 * 2 = 160字節,求解R行C列前面占用的空間就可以得到表達式:(R * 160 + C * 2 ) 字節。

實現代碼

assume cs:code, ds:data
data segment
	db 'Welcome to masm!',0
data ends
code segment
start:
	mov dh, 10	;行號 范圍 0 ~ 24
	mov dl, 3	;列號 范圍 0 ~ 79
	mov cl, 2	;顏色(取值范圍0 ~ 79)
	
	mov ax, data
	mov ds, ax
	
	mov si, 0;ds偏移
	mov di, 0;es偏移
	mov bl, cl	;bl保存需要改變的顏色
	
	mov ax, 0B800H
	mov es, ax;顯存位置
	
	mov al, dh
	mov ah, 160
	mul ah
	add di, ax	;行空間
	
	mov al, cl
	mov ah, 2
	mul ah
	add di, ax	;列空間
	
	call compare
	
	mov ax, 4c00h
	int 21h
	
compare:;調用子程序前的保存工作
	push cx
	push di
	push si
	
show_str:
	mov cl, ds:[si]
	mov ch, 0H
	jcxz ok	;循環結束
	mov es:[di], cl
	mov es:[di + 1], bl
	add di, 2
	inc si
	jmp short show_str
	
ok:;調用完子程序之后的恢復工作
	pop si
	pop di
	pop cx
	ret
code ends
end start

運行

在這里插入圖片描述

2.解決除法溢出的問題

問題

在這里插入圖片描述
在這里插入圖片描述

子問題描述

在這里插入圖片描述

提示

在這里插入圖片描述

Solution

問題主要用於解決除法溢出的問題。

程序不難,只是用於熟悉子程序結構、構建。

assume cs:code, ss:stack
stack segment
	db 8 dup (0)
stack ends

code segment
start:
	mov ax, stack
	mov ss, ax
	
	mov ax, 4240H	;被除數低位
	mov dx, 000FH	;被除數高位
	mov cx, 0AH	;除數
	call divdw
	
	mov ax, 4c00h
	int 21H
divdw:
	push ax	;將被除數低位壓棧
	
	mov ax, dx	;將被除數高位傳入ax
	mov dx, 0	;進行高位除法
	
	div cx	;ax / cx,公式中 H / N
	mov bx, ax	;bx保存 int(H / N)
	
	pop ax	;低數位出棧,此時dx中為rem(H / N),正好滿足 [ rem(H / N) * 65536 + L]
	
	div cx	;(dx * 16 + ax) / cx
	mov cx, dx
	mov dx, bx
	ret
code ends
end start

3.數值顯示

問題

在這里插入圖片描述

子程序描述

在這里插入圖片描述
在這里插入圖片描述

提示

在這里插入圖片描述
在這里插入圖片描述
讀者對本題應該非常熟悉,在《C語言程序設計》課程中應該完成過“打印一個數字的每位數字”,這道題其實也是那個經典的while循環,按照王爽老師的解析還是可以很輕松地完成的哦。

assume cs:code, ss:stack
stack segment
	db 10 dup (0)
stack ends

data segment
	db 10 dup (0)
data ends

code segment
start:
	mov ax, 12666
	mov bx, data
	mov ds, bx
	mov bx, stack
	mov ss, bx
	
	mov dx, 0
	mov si, 0;計數器,表示共有多少位
	mov di, 10	;充當除數
	call dtoc
	
	mov dh, 8
	mov dl, 3
	mov cl, 2
	call show
	
	
dtoc:
	mov cx, ax
	jcxz change	;如果ax已經是零,循環結束,將數據轉移到ds:[x]
	mov dx, 0
	
	div di	;10
	push dx	;將余數壓棧
	inc si	;計數器加一
	jmp short dtoc

change:
	mov cx, si
	mov di, 0	;充當ds偏移
	
getAns:	;從棧中彈出數據,並加上30H
	jcxz ok	;數據彈出完畢
	pop ax
	add ax, 30H
	mov [di], ax
	inc di
	dec cx
	jmp getAns

ok:
	ret
	
show:
	mov si, 0;ds偏移
	mov di, 0;es偏移
	mov bl, cl	;bl保存需要改變的顏色
	
	mov ax, 0B800H
	mov es, ax;顯存位置
	
	mov al, dh
	mov ah, 160
	mul ah
	add di, ax	;行空間
	
	mov al, cl
	mov ah, 2
	mul ah
	add di, ax	;列空間
	
	call compa
	
	mov ax, 4c00h
	int 21h
	
compa:;調用子程序前的保存工作
	push cx
	push di
	push si
	
show_str:
	mov cl, ds:[si]
	mov ch, 0H
	jcxz okk	;循環結束
	mov es:[di], cl
	mov es:[di + 1], bl
	add di, 2
	inc si
	jmp short show_str
	
okk:;調用完子程序之后的恢復工作
	pop si
	pop di
	pop cx
	ret
code ends
end start

運行結果

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM