1. 程式人生 > >《組合語言》王爽 課程設計1

《組合語言》王爽 課程設計1

將實驗7的資料顯示在螢幕上:

分析:先將 data 中的資料轉換成字串後儲存在 table 中再顯示,按行顯示

遇到的問題:loop迴圈中的程式程式碼太長,loop對IP的修改範圍(-128~127Bytes),導致編譯無法通過,所以將loop換成以下語句

m_loop:
    ;some code
    ...

    dec cx
    jcxz b_loop
    jmp m_loop

b_loop:
    mov ax, 4c00H
    int 21H

具體程式碼:

;《組合語言》課程設計1
;按行顯示,共21行,迴圈21次,cx迴圈計數
;每行按 "年份"、"總收入"、"僱員數"、"平均收入" 順序顯示
;將每一行的資料轉換成字串儲存到table,再顯示

assume cs:code, ds:data, ss:stack

data segment
	;21個年份,84個byte
	db '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983'
	db '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992'
	db '1993', '1994', '1995'
	
	;21年總收入,84個byte
	dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
	dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000
	
	;21年僱員人數,42個byte
	dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226
	dw 11542, 14430, 15257, 17800
	
	;21年人均收入,
	dw 5, 3, 42, 104, 85, 210, 123, 111, 105, 125, 140, 136, 153, 211, 199, 209, 224, 239
    dw 260, 304, 333
data ends

table segment
	db 32 dup (0)
table ends

stack segment
	db 32 dup (0)
stack ends

code segment
start:		
	mov ax, data
	mov es, ax			;(es): data段地址
	mov ax, table
	mov ds, ax			;(ds): table段地址 
	mov ax, stack
	mov ss, ax
	mov sp, 20H			;初始化棧
	
	mov cx, 21			;迴圈計數21次,1次迴圈顯示一行
	mov dh, 2			;顯示的起始行
	mov dl, 2			;顯示的起始列
	mov si, 0
	mov di, 0

m_loop:					;主迴圈
	push cx				;儲存當前迴圈數
	push dx				;儲存當前顯示行列
	push di				;(di) = 當前行
	mov bp, sp			;(bp) = (sp),即(ss:[bp] = di)
	
	;年份
	mov si, 0
	mov al, 4
	mov bl, byte ptr [bp]
	call get_offset
	mov cx, 4
y_loop:					;年份迴圈
	mov al, es:[di]
	mov ds:[si], al
	inc di
	inc si
	loop y_loop
	mov byte ptr ds:[si], 0		;年份結尾標誌
	mov dx, [bp+2]		;(dx) = (ss:[bp+2])
	mov cl, 2			;(cl) = 2,字型顏色
	call show_str
	
	;總收入dword型,資料起始位置es:[84]
	mov al, 4
	mov bl, byte ptr [bp]
	call get_offset
	mov ax, es:[di+84]	;總收入低16位
	mov dx, es:[di+86]	;總收入高16位
	call dtoc
	mov dx, [bp+2]
	mov dl, 12
	mov cl, 2
	call show_str
	
	;僱員人數word型,資料起始位置es:[168]
	mov al, 2
	mov bl, byte ptr [bp]
	call get_offset
	mov ax, es:[di+168]	;word型,進行divw除法,ax為低16位
	mov dx, 0			;dx為高16位,置0
	call dtoc
	mov dx, [bp+2]
	mov dl, 22
	mov cl, 2
	call show_str
	
	;平均收入word型,資料起始位置es:[210]
	mov al, 2
	mov bl, byte ptr [bp]
	call get_offset
	mov ax, es:[di+210]
	mov dx, 0
	call dtoc
	mov dx, [bp+2]
	mov dl, 32
	mov cl, 2
	call show_str 
		
	pop di
	pop dx
	pop cx
	inc di				;下一行
	inc dh				;下一行顯示起始位置,行 + 1,列不變
	dec cx
	jcxz b_loop
	jmp m_loop
b_loop:	
	mov ax, 4c00H
	int 21H
	
			
;子程式描述
;名稱:show_str
;功能:在指定的位置用指定的顏色,顯示一個以0結尾的字串
;引數:(dh) = 行號(取值範圍:0~24),(dl) = 列號(取值範圍:0~79)
;	   (cl) = 顏色,ds:[si]指向字串的首地址
;返回:無
show_str:
	push es
	push ax
	push bx
	
	mov si, 0
	mov ax, 0b800H
	mov es, ax
	mov ah, 0
	mov al, 160
	mul dh
	mov bx, ax
	mov ah, 0
	mov al, 2
	mul dl
	add bx, ax			;es:[bx]為顯示起始地址
	
	mov al, cl
	mov ch, 0
	
show_0:
	mov cl, ds:[si]
	jcxz show_1			;判斷是否為字串結尾標誌0
	mov es:[bx], cl
	mov es:[bx+1], al
	inc si
	add bx, 2
	jmp show_0
	
show_1:
	pop bx
	pop ax
	pop es
	ret

		
;子程式描述
;名稱:divdw
;功能:進行不會產生溢位的除法運算,被除數為dword型,除數為word型,
;	   結果為dword型
;引數:(ax) = dword型低16位,(dx) = dword型高16位,(cx) = 除數
;返回:(dx) = 結果的高16位,(ax) = 結果的低16位,(cx) = 餘數
divw:
	push ax
	mov ax, dx		;先進行高16位除法
	mov dx, 0		
	div cx			;餘數在(dx)中,商在(ax)中
	mov bx, ax		;將高位商在(bx)中儲存
	
	pop ax			;再進行低16位除法
	div cx			;餘數在(dx)中,商在(ax)中
	mov cx, dx		
	mov dx, bx		;(dx) = 結果高16位,(ax) = 結果低16位,(cx) = 餘數
	ret
	

;子程式描述
;名稱:dtoc
;功能:將資料轉化為字串,字串以0結尾
;引數:(dx) = dword型高16位,
;      (ax) = dword型低16位,
;	   ds:[si]指向字串的首地址
;返回:無
dtoc:
	mov si, 0
	mov bx, 0
	push bx			;字串結尾標誌入棧
dtoc_0:
	mov cx, 10		;(cx) = 除數	
	call divw
	add cx, 30H		;餘數 + 30H = 對應的字元ASCII碼
	push cx
	mov cx, dx		;判斷高位商是否為0
	jcxz dtoc_1		;為0繼續判斷低位商
dtoc_1:
	mov cx, ax		;判斷低位商是否為0
	jcxz dtoc_2		;為0則表示除盡,進行轉字串操作
	jmp dtoc_0		;否則繼續進行除法
dtoc_2:
	pop cx
	mov ds:[si], cl	;將字串傳入(ds)中
	jcxz dtoc_3
	inc si
	jmp dtoc_2
dtoc_3:
	mov si, 0
	ret
	
	
;子程式描述
;名稱:get_offset
;功能:獲取資料相對偏移位置
;引數:(al) = 資料型別長度
;      (bl) = 該類資料的第幾個
;返回:無
get_offset:
	mov ah, 0
	mul bl
	mov di, ax		;(di) = 相對該型別資料初始位置的偏移
	ret
	
code ends

end start

執行結果:

歡迎討論!