彙編語言 | 第16章 直接定址表(含檢測點16.1 16.2)

16.1 描述了單元長度的標號

前面的課程中,我們一直在代碼段中使用標號來標記指令、數據、段的起始地址。比如,下面的程序將code段中的a標號處的8個數據累加,結果存儲到b標號處的字中。
在這裏插入圖片描述
在這裏插入圖片描述

assume cs:code
code segment
	a db 1,2,3,4,5,6,7,8
	b dw 0
	
	start:
	mov si,0
	mov cx,8
	s:
	mov al,a[si]
	mov ah,0
	add b,ax
	inc si
	loop s
	mov ax,4c00h
	int 21h
	
code ends
end start	

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

檢測點16.1

下面的程序將code段中a處的8個數據累加,結果存儲到b處的雙字中,補全程序。

在這裏插入圖片描述

assume cs:code
code segment
    a dw 1, 2, 3, 4, 5, 6, 7, 8
    b dd 0

start: mov si, 0
        mov cx, 8

    s:  mov ax, a[si]	;a是dw型的,可以直接給ax
        add word ptr b[0], ax	;b是dd型的,ax只能和b的低位相加
        adc word ptr b[2], 0		;b的高位和0相加,使用adc進位加法是把低位進位加上
        add si, 2	;用si來控制a中的數據累加
        loop s     
        mov ax, 4c00H
        int 21H
code ends
end start

16.2 在其他段中使用數據標號

在這裏插入圖片描述

assume cs:code,ds:data
data segment
	a db 1,2,3,4,5,6,7,8
	b dw 0
data ends

code segment
	start:
	mov ax,data
	mov ds,ax
	
	mov si,0
	mov cx,8
	s:
	mov al,a[si]
	mov ah,0
	add b,ax
	inc si
	loop s
	
	mov ax,4c00h
	int 21h
	
code ends
end start	

在這裏插入圖片描述
在這裏插入圖片描述
可以將標號當作數據來定義,此時,編譯器將標號所表示的地址當作數據的值。
在這裏插入圖片描述
在這裏插入圖片描述

檢測點16.2

下面的程序將data段中a處的8個數據累加,結果存儲到b處的字中,補全程序。

在這裏插入圖片描述

assume cs:code,es:data
	
data segment
	a db 1,2,3,4,5,6,7,8
	b dw 0
data ends

code segment
	start:
	mov ax,data	;把es和data段相關聯
	mov es,ax
	
	mov si,0
	mov cx,8
	s:
	mov al,a[si]
	mov ah,0
	add b,ax
	inc si
	loop s
	
	mov ax,4c00h
	int 21h
code ends
end start

16.3 直接定址表

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

;用al傳送要顯示的數據

showbyte: 
	jmp short show
	table db '0123456789ABCDEF'	;table字符表
	
show:
	push ax
	push es
	
	mov ah,al
	shr ah,1
	shr ah,1
	shr ah,1
	shr ah,1	;右移4位,ah中得到高4位的值
	and al,00001111b 	;al中爲低4位的值
	
	mov bl,ah
	mov bh,0
	mov ah,table[bx]	;用高4位的值作爲相對table的偏移,取得對應字符,作爲要顯示的字節的高位
	
	mov bx,0b800h
	mov es,bx
	mov es:[160*12+40*2],ah
	
	mov bl,al
	mov bh,0
	mov al,table[bx]	;用低4位的值作爲相對於table的偏移,取得對應的字符,作爲要顯示字節的低位
	
	mov es:[160*12+40*2+2],al
	
	pop es
	pop bx
	ret

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

showsin:
	jmp short show
	
	table dw ag0,ag30,ag60,ag90,ag120,ag150,ag180 	;字符串偏移地址表
	ag0 db '0',0	;sin(0)對應字符串爲0,下同
	ag30 db '0.5',0
	ag60 db '0.866',0
	ag90 db '1',0
	ag120 db '0.866',0
	ag150 db '0.5',0
	ag180 db '0',0
	
show:
	push bx		;先把一些要使用的寄存器壓棧
	push es
	push si
	mov bx,0b800h
	mov es,bx	;es指向顯存區域
	
	;用以下角度值/30作爲相對於table的偏移,取得對應的字符串的偏移地址,放在bx中
	
	mov ah ,0	;最大也才180沒有超過255,用不上ah
	mov bl,30
	div bl		;除數爲8位,被除數爲ax,商放在al裏面
	mov bl,al		;商給bl,作爲table表的索引
	mov bh,0
	add bx,bx
	mov bx,table[bx]
	
	;以下顯示sin(x)對應的字符串
	mov si,160*12+40*2

shows:
	mov ah,cs:[bx]	;判斷是否讀到了0
	cmp ah,0
	je showret
	mov es:[si],ah
	inc bx
	add si,2
	jmp short shows
	
showret:
	pop si
	pop es
	pop bx
	ret

在這裏插入圖片描述


16.4 程序入口地址的直接定址表

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

子程序實現功能1:清屏

sub1: 
	push bx
	push cx
	push es
	mov bx,0b800h
	mov es,bx
	mov bx,0
	mov cx,2000
	
sub1s:
	mov byte ptr es:[bx],' '	;用空格覆蓋
	add bx,2
	loop sub1s
	
	pop es
	pop cx
	pop bx
	ret

子程序實現功能2:設置前景

sub2:
	push bx
	push cx
	push es
	
	mov bx,0b800h
	mov es,bx
	mov bx,1
	mov cx,2000
	
sub2s:
	and byte ptr es:[bx],11111000b	;把奇字節的第0、1、2位清零
	or es:[bx],al	;用or操作把012三位設置爲我們想要的顏色
	add bx,2
	loop sub2s
	
	pop es
	pop cx
	pop bx
	ret

子程序實現功能3:設置背景色

sub3:
	push bx
	push cx
	push es
	mov cl,4
	shl al,cl	;al用來傳送顏色,al的值爲0-7,設置背景色是456位,要把al左移4位、
	mov bx,0b800h
	mov es,bx
	mov bx,1	;顯存中的基地址爲屬性字節
	mov cx,2000
	
sub3s:
	and byte ptr es:[bx],10001111b	;第456位先置0,其他位不變
	or es:[bx],al	;es:[bx]和al相或,設置顏色
	add bx,2
	loop sub3s
	pop es
	pop cx
	pop bx
	ret

子程序實現功能4:向上滾動一行

sub4:
	push cx
	push si
	push di
	push es
	push ds
	
	mov si,0b800h
	mov es,si
	mov ds,si
	mov si,160		;ds:si指向第n+1行
	mov di,0		;es:di指向第n行
	cld		;設置正向傳輸
	mov cx,24	;共複製24行,整屏就24行
	
sub4s:
	push cx
	mov cx,160
	rep movsb 	;複製
	pop cx
	loop sub4s
	
	mov cx,80
	mov si,0

sub4s1:
	mov byte ptr [160*24+si],' ' 	;最後一行清空
	add si,2
	loop sub4s1
	
	pop ds
	pop es
	pop di
	pop si
	pop cx
	ret

我們可以將這些功能子程序的入口地址存儲在一個表中,它們在表中的位置和功能號相對應。對應關係爲:功能號*2=對應的功能子程序在地址表中的偏移。程序如下:

setscreen: 
	jmp short set
	table dw sub1,sub2,sub3,sub4
	set:
	push bx
	cmp ah,3	;判斷功能號是否大於3
	ja sret
	mov bl,ah
	mov bh,0
	add bx,bx	;根據ah中的功能號計算對應子程序在table表中的偏移,即功能號*2=偏移
	
	call word ptr table[bx]		;調用對應的功能子程序
	sret:
	pop bx
	ret

我們也可以將子程序setscreen用以下命令實現:

setscreen:
	cmp ah,0
	je do1
	cmp ah,1
	je do2
	cmp ah,2
	je do3
	cmp ah,3
	je do4
	jmp short sret
	
	do1:
	call sub1
	jmp short sret
	
	do2:
	call sub2
	jmp short sret
	
	do3:
	call sub3
	jmp short sret
	
	do4:
	call sub4
	jmp short sret
	
	sret:
	ret		

在這裏插入圖片描述

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