(二十八)《汇编语言(王爽)》 | 检测点 16.1、16.2


1. 预备知识

  • 先前,我们在代码段中使用标号来标记指令、数据或段的起始地址,这类标号仅仅表示内存单元的地址。我们还可以使用一种标号,这种标号不但表示内存单元的地址,还表示了内存单元的长度。
a db 1,2,3,4,5,6,7,8
b dw 0
  • 上述标号 a 和 b 后面没有冒号,它们同时描述内存地址和单元长度。如标号 a 描述了地址 code:0,和从这个地址开始以后的内存单元都是字节单元;标号 b 描述了地址 code:8,和从这个地址开始以后的内存单元都是字单元。
  • 因为这种标号包含内存单元的长度,所以可以借由它表示段中内存单元的地址。如:
mov ax,b 相当于 mov ax,cs:[8]
mov b,2 相当于 mov word ptr cs:[8],2
inc 相当于 inc word ptr cs:[8]
  • 一般情况下,我们不在代码段中定义数据,而是将数据定义到其他段。如果想在代码端中直接用数据标号访问数据,需使用 assume 将标号所在段与一个段寄存器联系起来。
assume cs:code,ds:data
data segment
	a ab 1,2,3,4,5,6,7,8
	b dw 0
data ends
start:
	mov ax,data
	mov ds,ax
	...
	mov al,a[si]	;使用标号访问数据,与段寄存器DS相关联
	...
	add b,ax		;使用标号访问数据,与段寄存器DS相关联
	...
  • 还可以将标号当作数据来定义,此时编译器将标号所表示的地址当作数据的值。
data segment
	a db 1,2,3,4,5,6,7,8
	b dw 0
	c dw a,b
data ends

相当于

data segment
	a db 1,2,3,4,5,6,7,8
	b dw 0
	c dw offset a,offset b
data ends

2. 检测点 16.1

下面的程序段将 code 段中 a 处的 8 个数据累加,结果存储到 b 处的 dword 中,补全程序。

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,____
		add ____,ax
		adc ____,0
		add si,____
		loop s
		mov ax,4c00h
		int 21h
code ends
end start
  • 标号 a 描述单元 cs:0,从这个单元开始,后面单元都是字单元;标号 b 描述单元 cs:10,从这个单元开始,后面单元都是双字单元。
  • 程序中包括 add 和 adc 两种加法指令,add 用于累加 a 处的数据、adc 用于处理进位数据。b 为双字单元,使用 b[0] 存储相加内容、b[2] 存储进位内容:
add word ptr b[0],ax
adc word ptr b[2],0
  • 由于 a 定义的是子单元,所以 si 每次偏移 2 个字节。
add si,2

整体代码为:

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]
		add word ptr b[0],ax
		adc word ptr b[2],0
		add si,2
		loop s
		mov ax,4c00h
		int 21h
code ends
end start

程序运行前,查看标号 a 和 标号 b 内存单元的内容。

请添加图片描述
程序运行后,查看标号 b 内存单元的内容。

请添加图片描述
此时,标号 b 的内容为 00000024h,为标号 a 单元的内容和。


3. 检测点 16.2

下面的程序段将 code 段中 a 处的 8 个数据累加,结果存储到 b 处的 dword 中,补全程序。

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 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
  • 标号 a 描述单元 ds:0,从这个单元开始,后面单元都是字节单元;标号 b 描述单元 ds:8,从这个单元开始,后面单元都是字单元。
  • mov al,a[si] 默认使用的段地址是数据段所在地址,且 assume 中 es 与 data 段相关联,缺失部分语句使用段寄存器 ES 指向 data 段:
mov ax,data
mov es,ax

整体代码为:

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 
	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

程序运行前,查看标号 a 和 标号 b 内存单元的内容。

请添加图片描述
程序运行前,查看标号 b 内存单元的内容。

请添加图片描述
此时,标号 b 的内容为 0024h,为标号 a 单元的内容和。


4. 总结

  • 标号除用于表示指令、数据或段的地址,还可以表示内存单元的长度。前者标号后面带冒号,后者不带冒号。
  • 在其他段中使用标号表示的数据时,需通过 assume 伪指令将标号所在段与某个段寄存器相关联。且在程序中,也要实现该关联。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值