实验七 寻址方式在结构化数据访问中的应用

在这里插入图片描述
下面的程序中,已经定义好了这些数据

;实验七  寻址方式在结构化数据访问中的应用

;编程  将data段中的数据 按照如下格式写到table段中,并计算21年中的人均收入(取整)
;结果也按照下面的格式保存在table段中
assume cs:code,ds:data,ss:stack
data segment
		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年的21个字符串  year   21*4=84

	
    	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
	;以上是表示21年公司总收入的21个数据   21*4=84
	
		dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    	dw 11452,14430,15257,17800
	;以上是表示21年公司的员工数量
data ends

table segment
			; '0123456789ABCDEF'
	db 21 dup('year sumn ne ?? ')
table ends

stack segment stack
	db	128 dup (0)
stack ends

先用debug查看这些数据在内存中的分布
在这里插入图片描述

;实验七  寻址方式在结构化数据访问中的应用

;编程  将data段中的数据 按照如下格式写到table段中,并计算21年中的人均收入(取整)
;结果也按照下面的格式保存在table段中
assume cs:code,ds:data,ss:stack
data segment
	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年的21个字符串  year

	
    	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
	;以上是表示21年公司总收入的21个数据
	
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    	dw 11452,14430,15257,17800
	;以上是表示21年公司的员工数量
data ends

table segment
		    ; '0123456789ABCDEF'
	db 21 dup('year sumn ne ?? ')
table ends

stack segment stack
	db	128 dup (0)
stack ends

code segment
	start:
		mov ax,stack
		mov ss,ax
		mov sp,128

		mov ax,data
		mov ds,ax ;数据从哪里来

		mov ax,table
		mov es,ax  ;数据到哪里去

		mov si,0  
		;年份在data中'1975'中的1偏移地址为0   		        	;ds:[si]
		mov di,84 
		;公司总收入的第一个数据16,它的偏移地址在data段中是84(54H)    ;ds:[di]
		mov bx,168
		;公司的员工数量,第一个数据3,在data段中的偏移地址是168(A8H)  ;ds:[bx]
		mov bp,0  
		;'year sumn ne ?? '的第一个字母y,在table段中的偏移地址是0      ;es:[bp]
		;bp寄存器默认的段寄存器是ss,bp为偏移地址->ss:[bp]
	
		mov cx,21;处理21行

		;处理年份	
inputtable:	push ds:[si]
		pop es:[bp]
		push ds:[si+2]
		pop es:[bp+2]

		;处理总收入——低16位放在AX,高16位放在DX
		mov ax,ds:[di]
		mov dx,ds:[di+2]
		mov es:[bp+5],ax
		mov es:[bp+7],dx
		     	;  '0123456789ABCDEF'
		;db 21 dup('year sumn ne ?? ') ;低位放到5,高位放到7
	
		;处理员工数量
		push ds:[bx]
		pop es:[bp+0AH]
		;这里用div 内存 ;因为寄存器不够用了
		div word ptr ds:[bx]
		mov es:[bp+0DH],ax
		
		add si,4
		add di,4
		add bx,2
		loop inputtable

		mov ax,4c00h
		int 21h
	

code ends
end start

代码改进:增加了代码可读性,已经减少寄存器的使用

;实验七  寻址方式在结构化数据访问中的应用

;编程  将data段中的数据 按照如下格式写到table段中,并计算21年中的人均收入(取整)
;结果也按照下面的格式保存在table段中
assume cs:code,ds:data,ss:stack
data segment
	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年的21个字符串  year

	
    	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
	;以上是表示21年公司总收入的21个数据
	
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    	dw 11452,14430,15257,17800
	;以上是表示21年公司的员工数量
data ends

table segment
		; '0123456789ABCDEF'
	db 21 dup('year sumn ne ?? ')
table ends

stack segment stack
	db	128 dup (0)
stack ends

code segment
	start:
		mov ax,stack
		mov ss,ax
		mov sp,128

		mov ax,data
		mov ds,ax

		mov ax,table
		mov es,ax

		mov si,0  
		;年份在data中'1975'中的1偏移地址为0   		        	;ds:[si]
		mov di,21*4 
		;公司总收入的第一个数据16,它的偏移地址在data段中是84(54H)    ;ds:[di]
		mov bx,21*4+21*4
		;公司的员工数量,第一个数据3,在data段中的偏移地址是168(A8H)  ;ds:[bx]
		mov bp,0  
		;'year sumn ne ?? '的第一个字母y,在table段中的偏移地址是0      ;es:[bp]
		;bp寄存器默认的段寄存器是ss,bp为偏移地址->ss:[bp]
	
		mov cx,21;处理21行

		;处理年份	
inputtable:	push ds:[si+0]
		pop es:[bp+0]
		push ds:[si+2]
		pop es:[bp+2]

		;处理总收入——低16位放在AX,高16位放在DX
		mov ax,ds:[si+21*4]
		mov dx,ds:[si+21*4+2]
		mov es:[bp+5],ax
		mov es:[bp+7],dx
			;  '0123456789ABCDEF'
		;db 21 dup('year sumn ne ?? ') ;低位放到5,高位放到7
	
		;处理员工数量
		push ds:[bx]
		pop es:[bp+0AH]
		;这里用div 内存 ;因为寄存器不够用了
		div word ptr ds:[bx]
		mov es:[bp+0DH],ax
		
		add si,4
	;	add di,4
		add bx,2
		loop inputtable

		mov ax,4c00h
		int 21h
	

code ends
end start


具体代码:

assume cs:codesg,ds:data,ss:table
data segment ;定数据段
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
	db '1993','1994','1995'
	;定义字节数据,存放年
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
	;定义双字数据,存放收入(被除数)。
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
	dw 11452,14430,15257,17800
	;定义字形数据,存雇员人数(除数)。
data ends
table segment
    db 21 dup ('year summ ne ?? ')
table ends
;定义字形数据,21个年平均值
codesg segment
start:  mov ax,data 
        mov ds,ax 
		;初始数据段
        mov ax,table 
        mov ss,ax 
		;将表格定位给栈段(用栈段存放平均值)
        mov bx,0 
        mov si,0    ;数据段中年份中的数据
        mov bp,0    ;表格第一行
        mov cx,21   ;21行所以21次循环 
s0:mov ax,[bx+si]   ;读取数据段中的年份数据的前2个字节,交给AX
   mov [bp+0],ax    ;年份数据的前2个字节放入到表格(因为表格前面定义给了SS栈段)
   add si,2         ;指向年份后2个字节
   mov ax,[bx+si]   ;读取数据段中年份数据的后2个字节,交给AX
   mov [bp+2],ax    ;年份数据的后2个字节放入到表格
   add si,2         ;指向数据段中下一个年份
   add bp,10h       ;转到下一行
   loop s0 
;S0循环是将数据段中(0-53H)的年份读取出来,放到表格的年份(0-3)列中
   mov cx,21        ;21次循环处理收入
   mov bp,0         ;收入的行
   mov si,0         ;数据段中收入数据指针
s1:mov ax,[bx+si+84] ;因为数据段中年份数据是21行4个字节,共占了数据段84个字节。
                     ;所以收入第一个数据是从数据段第84个字节处开始的,读取后给AX。
   mov [bp+5],ax     ;收入数据放入到表格,因为年份占了前4列,加上空格,所以放到第5列
   add si,2          ;处理数据的后2个字节
   mov ax,[bx+si+84] ;读取数据的后2个字节,放入AX
   mov [bp+7],ax     ;收入数据的后2个字节放入到表格
   add si,2          ;指向下一个数据
   add bp,10h        ;指向下一行
   loop s1 
;S1循环是将数据段中(54H-0A7H)的收入读取出来,放到表格的收入(5-8)列中
   mov cx,21          ;21次循环
   mov bp,0           ;定位表格的行
   mov si,0           ;数据段中雇员数据指针 
s2:mov ax,[bx+si+168] ;因为数据段中年份与收入数据共占了168个字节。
                      ;所以雇员第一个数据是从数据段第168个字节处开始的,读出给AX
   mov [bp+10],ax     ;将雇员数据放入到表格
   add si,2           ;指向数据段下一个雇员数据
   add bp,10h         ;指向下一行
   loop s2            
;S2循环是将数据段中(0A8H-0D1H)的雇员读取出来,放到表格的收入(A-B)列中
   mov cx,21          ;21次循环,计算平均收入值
   mov bp,0 
s3:mov ax,[bp+5]      
   mov dx,[bp+7]      ;放入被除数(收入),高位给DX,低位给AX
   div word ptr [bp+10] ;放入除数(雇员)
   mov [bp+13],ax       ;商(平均值)放入表格
   add bp,10h           ;指向下一行
   loop s3 
;S2循环是计算平均值,放到表格的人均收入(D-E)列中
    mov ax,4c00h
    int 21h
codesg ends
end start
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值