汇编语言(第四版)第八章 实验7 习题解答

Power idea 公司从1975年成立一直到1995年的基本情况如下:

 下面的程序中,已经定义好了这些数据:

assume cs:codesg,ds:datasg

datasg 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 个字符串

    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 个 dword 型数据

    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
	dw 11542,14430,15257,17800
    ;以上是表示21年公司雇员人数的 21 个 word 型数据
datasg ends

table segment
    db 21 dup('year summ ne ?? ')
table ends

编程,将data段中的数据按如下格式写入到 table 段中,并计算 21 年中的人均收入(取整),结果也按照下面的格式保存在 table 段中。

分析:本实验中的表格规格是固定的,操作起来就相对简单一些。我们可以直接遍历数据段或者按行遍历数据段

方法一:直接遍历数据段

(1)先遍历年份、收入、人数

由于表格的每行长度为16字节,如果当前表格中遍历的年份位置是es:[di],则下一年在表格的位置是es:[di+16],以此类推将年份、总收入、人数依次案列填入表格中,每次遍历后递增4字节或2字节(年份、总收入占4个字节,总人数占两个字节,还要注意空格),遍历总收入时将数据段总收入首地址保存在栈中,之后计算平均值要用到。

(2)计算平均值

在遍历数据段人数填入表格时时,将数据段总收入首地址从栈中弹出,根据首地址读取总收入放入AX和DX中,将总人数放入BX中,利用div指令计算平均值填入表格中。

assume cs:codesg,ds:datasg,es:table,ss:stacksg

datasg 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 11542,14430,15257,17800

datasg ends

table segment
    db 21 dup('year summ ne ?? ')
table ends

stacksg segment
    dw 2 dup (0) ;栈段用于保存总收入首地址,也可以不使用栈直接用 ds:54h 表示栈段首地址(因为表格固定)
stacksg ends

codesg segment

start:mov ax,datasg   ;初始化数据段、table段、栈段地址
      mov ds,ax
      mov ax,table
      mov es,ax
      mov ax,stacksg
      mov ss,ax
      mov cx,21
      mov bx,0
      mov si,0
      mov di,0
s0:                      ;将年份按列填入表格
      mov ax,[si]
      mov es:[di],ax
      mov ax,[si+2]
      mov es:[di+2],ax
      add di,16
      add si,4
      loop s0

      mov di,5
      mov cx,21        ;保存总收入首地址,之后计算平均值要用
      push si
s1:                    ;将总收入按列填入表格
      mov ax,[si]
      mov es:[di],ax
      mov ax,[si+2]
      mov es:[di+2],ax
      add di,16
      add si,4
      loop s1

      mov di,0ah
      mov cx,21
s2:                    ;将总人数按列填入表格,同时计算平均值
      mov ax,[si]
      mov es:[di],ax
      ;;;; 将数据段总人数当前地址临时放入栈中,让出si寄存器
      pop bx
      push si
      mov si,bx
      ;;;;; 计算平均值
      mov bx,ax
      mov ax,[si]
      mov dx,[si+2]
      div bx
      ;;;; 将平均值填入表格中,同时栈中si寄存器恢复
      mov es:[di+3],ax
      add si,4
      pop bx
      push si
      mov si,bx

      add di,16
      add si,2
      loop s2

      mov ax,4c00h
      int 21h

codesg ends

end start

方法二:按行遍历数据段

 

 在按行进行遍历时,先确定数据段中三种数据的基址,如上图所示,年份:ds:00H、总收入:ds:54H、人数:ds:a8H,然后根据基址加上偏移量所得地址找到数据后逐个按行填入表格,遍历下一行时,年份、总收入的偏移量+4,人数的偏移量+2 逐行遍历时,还要同时计算平均值填入表格即可。

assume cs:codesg,ds:datasg,es:table

datasg 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 11542,14430,15257,17800

datasg ends

table segment
    db 21 dup('year summ ne ?? ')
table ends

codesg segment

start:mov ax,datasg    ;初始化数据段、table段
      mov ds,ax
      mov ax,table
      mov es,ax
      mov si,0
      mov di,0
      mov bx,0
      mov cx,21

s0:                        ;按行循环填入表格
      mov ax,0h[bx]
      mov es:0h[di],ax    ;将每行的年份填入表格
      mov ax,2h[bx]
      mov es:2h[di],ax

      mov ax,54h[bx]    ;将每行的总收入填入表格
      mov es:5h[di],ax
      mov dx,56h[bx]    ;这里使用dx存储总收入高位部分,后面计算平均值要用到
      mov es:7h[di],dx

      mov ax,0a8h[si]    ;将每行的人数填入表格
      mov es:0ah[di],ax

      mov ax,54h[bx]     ;之前ax存储总收入低位部分被覆盖了,要重新存一下
      div word ptr 0a8h[si];计算平均值,由于bx要存储偏移量,故除数直接从内存寻址。
      mov es:0dh[di],ax    ;将内存结果填入表格

      add bx,4    ;年份、总收入占4个字节,每次+4
      add si,2    ;人数只占两个字节,每次只需+2
      add di,16   ;表格每行占16个字节,遍历下一行时要+16

      loop s0

      mov ax,4c00h
      int 21h

codesg ends

end start

将数据填入表格后如下所示:

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值