汇编语言 | 第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		

在这里插入图片描述

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值