汇编语言:寻址方式在结构化数据访问中的应用——计算人均收入

有一年多没有在CSDN上发博文了。人的工作重心总是有转移的,庆幸一直在做着有意义的事。
  今天的内容,是为汇编语言课程更新一个实验项目。
  
  本方案修改自王爽编《汇编语言》第4版P172“实验7寻址方式在结构化数据访问中的应用”

【数据描述】

烟园科技公司从2004年成立一直到2023年的基本情况如下。

年份总收入(万元)雇员(人)人均收入(万元)
2004227?
20053829?
2006135613?
2007239028?
2008800038?
……
2023593700017800?

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

assume cs:codesg
data segment
    db '2004','2005','2006','2007','2008','2009','2010','2011','2012','2013'
    db '2014','2015','2016','2017','2018','2019','2020','2021','2022','2023'
    ;以上是表示20年的20个字符串
    dd 22,382,1356,2390,8000,16000,24486,50065,97479,140417
    dd 197514,345980,590827,803530,1183000,1843000
    dd 2759000,3753000,4649000,5937000
    ;以上是表示20年公司总收入的20个dword型数据
    dw 7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800
    ;以上是表示20年公司雇员人数的20个word型数据
data ends
table segment
    db 20 dup('year summ ne ??')
table ends`

【任务】

请编程序,将data段中的数据按如下格式整理到table段中,并计算20年中的人均收入(取整),记录到table段的相应位置上。
  在table段中,一年的数据占16个字节,各字节分配如下表所示。
在这里插入图片描述
说明:与教材中提供的方案相比,每一部分的偏移地址为偶数,是更有效率的解决方案,而预留“保留”空间,既能让每一条记录所点空间保持16的倍数上(这是一个很好的特征),也为系统未来扩充等提供方便。

【提示】

①要做的工作主要是将data段中的数据复制到table段中,类似将数据做一个“扭转”;
②可将data段中的数据看成是多个数组,用DS指标该数据段,而将table中的数据看成是一个结构型数据的数组,每个结构型数据中包含多个数据项,用ES指示该数据段;
③寻址方式建议:可用bx定位每个结构型数据,用idata定位数据项,用si定位数组项中的每个元素,对于table中的数据的访问可采用[bx].idata和[bx].idata[si]的寻址方式;
④程序结构方面:可以将程序分为四块,分别用四个循环处理——复制年份、复制总收入、复制雇员数、计算人均收入,当然,这四个循环可以合并以提高效率。

【参考解答】

assume cs:codesg, ds:data
data segment
    db '2004','2005','2006','2007','2008','2009','2010','2011','2012','2013'
    db '2014','2015','2016','2017','2018','2019','2020','2021','2022','2023'
    ;以上是表示20年的20个字符串
    dd 22,382,1356,2390,8000,16000,24486,50065,97479,140417
    dd 197514,345980,590827,803530,1183000,1843000
    dd 2759000,3753000,4649000,5937000
    ;以上是表示20年公司总收入的20个dword型数据
    dw 7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800
    ;以上是表示20年公司雇员人数的20个word型数据
data ends

table segment
    db 20 dup('YearSummNeAv????')
table ends

;定义代码段
codesg segment
start: 
    mov ax, data
    mov ds, ax

    mov ax, table
    mov es, ax

    ;复制年份
    mov cx, 20
    mov si, 0   ;data段的数据项
    mov bx, 0   ;table段年份的起始偏移地址
s1:
    mov ax, [si]      ;取data段中年份的前两字节
    mov es:[bx], ax   ;向table中复制年份的前两字节
    mov ax,[si+2]     ;取data段中年份的后两字节
    mov es:[bx+2], ax ;向table中复制年份的后两字节
    add si, 4         ;指向data段的下一个数据项
    add bx, 16        ;指向table中下一年的位置
    loop s1

    ;复制总收入
    mov cx, 20
    mov si, 0   ;data段的数据项
    mov bx, 4   ;table段总收入的起始偏移地址
s2:
    mov ax, [si+80]      ;取data段中总收入的前两字节
    mov es:[bx], ax      ;向table中复制总收入的前两字节
    mov ax,[si+82]       ;取data段中总收入的后两字节
    mov es:[bx+2], ax    ;向table中复制总收入的后两字节
    add si, 4            ;指向data段的下一个数据项
    add bx, 16           ;指向table中下一年的位置
    loop s2

    ;复制雇员人数
    mov cx, 20
    mov si, 0   ;data段的数据项
    mov bx, 8   ;table段雇员人数的起始偏移地址
s3:
    mov ax, [si+160]     ;取data段中雇员人数
    mov es:[bx], ax      ;向table中复制雇员人数的前两字节
    add si, 2            ;指向data段的下一个数据项
    add bx, 16           ;指向table中下一年的位置
    loop s3

    ;计算人均收入
    mov cx, 20
    mov bx, 0   ;table段雇起始偏移地址
s4:
    mov ax, es:[bx+4]      ;取总收入低16位
    mov dx, es:[bx+6]      ;取总收入高16位
    div word ptr es:[bx+8] ;除以雇员数,完成除法,商存放在AX中
    mov es:[bx+10], ax     ;存储人均收入
    add bx, 16             ;指向table中下一年的位置
    loop s4

    mov ax,4c00h
    int 21h
codesg ends
end start

下面是程序运行后看到的一部分数据:
在这里插入图片描述

【进一步改进】

参考解答中使用了并行的4个循环。观察到循环中寻址方式一致,将循环适当合并,是可能且会获得效率上提升的。
  用这个结构试着通思路,再改进出更高效率的解决方案,值得同学们一试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522838.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nodejs应用程序以守护进程daemon的方式启动,容器化部署的时候一直部署出错,导致无法成功启动程序。

一、背景 nodejs应用程序使用Egg.js 框架脚本命令,见package.json: "scripts": {"debug": "egg-bin debug","clean": "easy clean","build": "easy build prod","start&…

数字逻辑分析仪初体验

为啥会用到这玩意儿,要从一个荒诞的需求开始。想在市面上找一款特别低空飞行的监控,而且不想它一直开着监控,最好是我在外面远程指挥它起飞,飞去厨房,飞去洗手间,甚至飞去阳台,查看水龙头情况啊…

Redis性能瓶颈与安全隐患排查验证纪实

在写《Redis怎样保证数据安全?》这篇文章,我是有对redis设置密码需要哪些步骤,设置密码的性能损耗有验证的。这就涉及到要对redis的配置做修改。 开始时我是打算采用直接使用redis配置文件的方式。所以我从redis官网下载了一个默认的配置文件…

C++搭建深度学习的推理框架

我们的目的是:借助C++搭建一个类似于pytorch,tensorflow的深度学习框架,对标pytorch,tensorflow实现对应的功能。由于本人能力有限,下面本人将借助C++搭建一个简单的全连接神经网络,并且尝试解释里面的算子定义和计算图构建。 算子定义 回顾pytorch里面搭建的全连接神经网…

where 函数

Pandas 中的 where 函数 在 Pandas 中,where 函数用于替换不满足条件的值。具体来说,它返回一个与原始 DataFrame 或 Series 形状相同的新对象,但所有不满足条件的值都被替换为指定的值(默认为 NaN)。 对于 DataFram…

数据结构——二叉树链式结构的实现

大家好我是小锋,今天我们来学习的是二叉树链式结构的实现 首先我们来学习一下二叉树的基本操作 在看二叉树基本操作前我们来回顾下二叉树的概念, 二叉树是: 1. 空树 2. 非空:根节点,根节点的左子树、根节点的右…

软件团队工作的一些认识和方法,由西游记取经团队说开去

软件开发往往是由公司内外各个岗位人员通力协作才能完成工作目标,涉及团队、问题、目标、管理、协作、检查多个方面。 典型团队分析:西游记取经团队 优点 团队主管的目标特别明确:西天取经 团队有上级的得力支持:唐王、观音、如…

32-数据处理:如何高效处理应用程序产生的数据?

如何更好地进行异步数据处理。 一个大型应用为了后期的排障、运营等,会将一些请求数据保存在存储系统中 。例如:应用将请求日志保存到 Elasticsearch 中,方便排障;网关将 API 请求次数、请求消息体等数据保存在数据库中&#xff…

怎么用二维码来分享视频?视频二维码制作的简单方法

怎么用二维码来分享视频呢?为了能够更快速的将视频传递给其他人,所以现在很多人都使用生成二维码的方式,让其他人通过扫码来查看视频内容,从而实现多人同时扫码看视频的效果。这种方式也不会占用用户的内存和流量,通过…

【java的本地锁到分布式锁介绍】

文章目录 1.java本地自带锁介绍及应用synchronized(1)synchronized原理和优化(2)synchronized作用(3)synchronized的使用 CAS(1) CAS原理(2)CAS和synchronized优缺点 lock 2.分布式锁…

复习软考有哪些好的刷题APP?

这里为大家带来一些好用而且免费的软考刷题app,软考每年有两次,也渐渐成为很多人都会去考的了,这里推荐的这些软件上面的资料很新很齐全,各种科目类型都是有的,而且有解析,非常的实用哦! 1.希赛…

qt 打印日志

在 Qt Creator 中,将 QDebug、QInfo、QWarning、QCritical 和 QFatal 打印的日志输出到指定文件,需要设置 Qt 的消息处理机制。这通常涉及到安装一个自定义的消息处理器,该处理器将日志消息重定向到文件。以下是一个基本的步骤指南&#xff1…

聊聊Linux内核中内存模型

介绍 在Linux中二进制的程序从磁盘加载到内存,运行起来后用户态是使用pid来唯一标识进程,对于内核都是以task_struct表示。二进制程序中的数据段、代码段、堆都能提现在task_struct中。每一个进程都有自己的虚拟地址空间,虚拟地址空间包含几…

校园抄表电表系统

校园抄表电表系统是一种专门为学校宿舍、教学楼等校园建筑设计的电能计量和管理解决方案。随着校园数字化管理水平的提升,传统的电表抄录方式已经无法满足现代化校园管理的需求。因此,校园抄表电表系统应运而生,它通过自动化、信息化技术&…

一文读懂模块化赛道新的头部公链Meta Earth

加密货币诞生了15年后已经形成一定的规模,作为互联网和金融的延伸,加密货币也逐渐融合了人类经济的规律周期中,而这规律似乎早已被中本聪写入区块链上,那就是比特币的4年减半机制,也许是对传统金融和人类社会的洞察&am…

C++从入门到精通——类对象模型

类对象模型 前言一、如何计算类对象的大小问题 二、类对象的存储方式猜测对象中包含类的各个成员代码只保存一份,在对象中保存存放代码的地址只保存成员变量,成员函数存放在公共的代码段问题总结 三、结构体内存对齐规则四、例题结构体怎么对齐&#xff…

设计模式总结-适配器模式

适配器模式 模式动机模式定义模式结构适配器模式实例与解析实例一:仿生机器人实例二:加密适配器 总结 模式动机 在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式。 通常情况下,客户端可以通过目标类的接口访问它所提供的…

【PLC+Python】上位机通过snap7实现与西门子PLC通讯并用Tkinter可视化——(2)Python通讯和可视化

一 背景说明 计划通过西门子 S7-1200(CPU 1212C-DCDCDC),进行PLC与设备间的数据监控。但 TIA Portal V15.1 的交互数据非专业人员很难一目了然,又不想专门购买西门子的可编程屏幕,所以拟采用 python-snap7 模块实现上位…

MQTT 5.0 报文解析 01:CONNECT 与 CONNACK

在 MQTT 5.0 报文介绍 中,我们介绍了 MQTT 报文由固定报头、可变报头和有效载荷三个部分组成,以及可变字节整数、属性这类 MQTT 报文中的通用概念。现在,我们将按照实际的用途来进一步介绍各个类型的报文的组成。首先,我们将专注于…

初识Java中的NIO

1.概述 Java NIO 全称java non-blocking IO ,是指 JDK 提供的新 API。从 JDK1.4 开始,Java 提供了一系列改进的输入/输出新特性,被统称为 NIO(即 New IO),是同步非阻塞的。NIO采用内存映射文件的方式来处理输入输出,NI…