IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 汇编语言:实验七 寻址方式在结构化数据访问中的应用 -> 正文阅读

[Python知识库]汇编语言:实验七 寻址方式在结构化数据访问中的应用

话不多说,上图(原题为王爽老师的汇编语言P161):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Solution

如果用现在的高级语言来完成本题可以说是小菜一碟,但如果是只能使用几个简单的寄存器的和一些基础得不行的汇编语言,笔者作为初学者,认为这个还是有难度的。

如何解决此问题?乍一看这些数据真的是让人眼花缭乱,题中给出的格式更是令本人摸不着头脑,但在一步一步地分析之后,有着一定的高级语言编程基础,便有了这样的感觉:
题中给出的数据段(data segment)分为三大块:

  • 首先是字节型数据,每个元素占 1 个字节,与C语言中的字符类型char相似,如 ‘1975’ 等价于 ‘1’, ‘9’, ‘7’, ‘5’ 四个字符。
  • 第二块是double word 双字类型,每个元素占 4 字节(32 bits),可以类比于C语言中的有符号整型 (signed int 类型)。
  • 第三个类似于第二块数据,同样是整型数据,字(word)类型限制了每个元素的空间为 2 字节。
    这些排列整齐,并且每块都是相同类型的元素也就是高级语言中数组的雏形。
如何访问数组元素?

C语言中我们使用如 arr[ i ] 的方式对每个元素进行访问,在汇编当中有与之相似的方法: address[ offset ], address 表示首地址,offset表示相对于address的偏移

据此,需要求得各个"块"的首地址:

第一块(年份),因为是data segment的首位值,块首地址就是0H,本块共有21个元素,每个元素占 4 字节,那么一共占用 4 * 21 = 84字节,转换为十六进制就是 54H,因此本块占有的空间地址范围为 0 ~ 53H(这里地址是从0开始的,所以只能到53H)
在这里插入图片描述
第二块(公司总收入),同样的计算方式,块首地址是上一块的末端加一,53H + 1H = 54H, 本块也是21个元素,每个元素(double word)占用 4 字节,一共占用 4 * 21 = 84字节,54H + 54H - 1 = A7H;
在这里插入图片描述

第三块(公司雇员人数),同样得到块首地址: A7H + 1H = A8H
在这里插入图片描述

数据拷贝

明白了如何访问,那么接下来就要通过访问完成数据从data段到table段的拷贝,刚开始笔者没想到 es段寄存器,所以傻乎乎地使用了一个段寄存器ds来回切换… …这里介绍直接使用es的更简洁的编写方式。

首先,将两个数据段的首地址写入到 ds、es,以便完成后续地访问工作。
在这里插入图片描述
存储好了段位置,就可以显示地指定想要访问的数据段。
还需要做的一件事是:用寄存器保存各个段的偏移,说白了就是现在知道了数据的大块范围,但是需要的每一个具体的元素,因为8086CPU寄存器最多装入两个字节的数据,因此记录偏移位置是有必要的: 很凑巧的是,对于第一块的数据,每次需要操作 4 个字节,如 ‘1975’, 同样,对于第二块数据,double word 也是每次操作四个字节,所以可以只用一个寄存器表示偏移(每次更新偏移位置都是 + 4,往后偏四个字节即可),对于第三块数据,很遗憾,每次只需要偏移两个字节,与前两块的偏移"速度"不一致,必须额外使用一个寄存器去记录。
在这里插入图片描述

存放年份、公司总收入、公司人数

		;存放年份
	s:	mov ax, [bx]
		mov es:[di], ax
		mov ax, [bx + 2]
		mov es:[di + 2], ax
		;存放公司总收入
		mov ax, 54h[bx]	;第一个年收入的段基址 54H
		mov dx, 56H[bx]
		mov es:5h[di], ax
		mov es:7h[di], dx
		;存放公司人数
		mov ax, 0A8H[si]	;第一个人数的段基址 A8
		mov es:0AH[di], ax

存放公司总收入

这块需要使用到div指令,除数为word型时,需要同时使用 AX、DX来存储被除数,其中规则如下:
在这里插入图片描述
代码如下:
在这里插入图片描述
本次循环到此就结束了,为了循环正常进行,需要更新之前的偏移寄存器。
在这里插入图片描述

完整代码

assume cs:codesg
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年份 0 ~ 83 -> 0 ~ 53H
	
	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
	;以上表示21年公司总收入 84 ~ 167 -> 54 ~ 0A7H
	
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
	dw 11542,14430,15257,17800
	;以上是表示21年公司雇员人数 164 ~ 205 -> A8 -> 0CDH
data ends

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

codesg segment
start:mov ax, data
		mov ds, ax
		mov ax, table
		mov es, ax	;使用拓展段寄存器
		
		mov bx, 0	;data段偏移
		mov si, 0	;年份、收入的偏移
		mov di, 0	;雇员人数偏移
		mov cx, 21	;循环次数
		;存放年份
	s:	mov ax, [bx]
		mov es:[di], ax
		mov ax, [bx + 2]
		mov es:[di + 2], ax
		;存放公司总收入
		mov ax, 54h[bx]	;第一个年收入的段基址 54H
		mov dx, 56H[bx]
		mov es:5h[di], ax
		mov es:7h[di], dx
		;存放公司人数
		mov ax, 0A8H[si]	;第一个人数的段基址 A8
		mov es:0AH[di], ax
		;计算人均收入并存放
		mov ax, 54H[bx]
		mov dx, 54H[bx + 2]	;初始化被除数 AX 存放低位
		div word ptr ds:0A8H[si]	;除以人数
		mov es:0dH[di], ax	;将商写入到table
		;为下一次循环做准备
		add bx, 4	;年份 and 收入 偏移
		add si, 2	;雇员的偏移
		add di, 16	;di确定的是table的行基址
		loop s
		
		mov ax, 4c00h
		int 21h
codesg ends
end start
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:40:50  更:2021-09-08 10:41:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 14:05:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码