《汇编语言》第四版(王爽著)实验七

该文详细描述了一个汇编语言实验的过程,涉及数据段与表格段的数据写入,包括字节、字和双字的处理,以及debug调试步骤。实验通过计算人均收入展示了对内存地址、数据类型和寄存器的运用,最终验证了程序的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.实验内容

实验内容为将 data 段中的数据按照表格的形式写入到 table 段中,并计算 21 年中的人均收入

3.jpg

2.前置知识

  1. 1个字节---->占一个内存空间
  2. 1个字---->占两个内存空间
  3. 1个双字节---->占四个个内存空间
  4. dd 16 中 16 是十进制数,转为 debug 中就是 00000010,一共八位16进制数,占四个字节
  5. dw 16 在 debug 中就是 0010,一共四位16进制数,占两个字节

3.实验过程

  1. 实验思路

    1. 首先看 data 段中的各个数据的位置,大概算出每个数据的内存空间地址

    2. 其次看 table 段表中的各个数据的内存空间地址

    3. 在想各个寄存器有什么用

      1. cs:存放代码段地址
      2. ds:存放 data 段中数据的段地址
      3. ss:存放 table 段中数据的段地址
      4. ax:传输数据用、做除法用
      5. di:用于记 data 中的数据位置
      6. bp:用于记 table 的行
      7. si:用于记 table 的列
    4. 最后开始操作

    5. 先把年份写进去表中

    6. 把总收入写进表中

    7. 把公司雇员人数写进表中

    8. 最后计算公司人均收入

  2. 代码和注释如下

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 ?? ')
	db 0,0,0,0,0,0,0,0  	;用于建立栈空间
table ends

codesg segment
	start:
		mov ax,data   
		mov ds,ax   				;使 ds 指向 data 段
		mov di,0						;ds:di指向 data 段中的第一个单元
		
		mov ax,table
		mov ss,ax  					;使 ss 指向 table 段
		mov bp,0	
		mov si,0
		
		mov cx,21  					;外层循环,一共21个数据,就需要循环21次
	s0:
		mov sp,0160h  			;使 ss:sp 指向 table:0160h,以免影响到里面的数据
		push cx  						;储存外层循环次数,以免内存循环次数覆盖掉外层循环次数
		mov cx,4 						;内层循环
	s1:
		mov al,ds:[di]  		;进行字节操作,所以用 al 
		mov ss:[bp+si],al   ;让  ds:[di] 的内容放进表 ss:[bp+si] 中
		inc di  						;di=di+1
		inc si 							;si=si+1,因为进行字节操作,内存空间加一即可
		loop s1  						;结束内存循环
		mov si,0  					;si作为表中的列,一定要清零,不然就下一列了
		add bp,10h 					;进行行加,让数据写入表中的下一行
		pop cx  						;外层循环出栈
		loop s0
		
	mov bp,0  						;表行清零,重回第一行写入数据
	mov cx,21
	s3:
		mov ax,ds:[di]      ;由于di没有清零,所以保留数据,继续进行累加
		mov ss:[bp+5],ax  	;看 table 表让我们写的位置,所以要加个 5
		mov ax,ds:[di+2]  	;进行双字型数据操作,由于寄存器只有 16 位,那只能分两步进行
		mov ss:[bp+7],ax  	;由于前面进行了一个字的操作,所以这个内存空间要加 2
		add di,4  					;进行了双字节操作,就要加4
		add bp,10h					;进行行加,让数据写入表中的下一行
		loop s3 
		
	mov bp,0 							;表行清零,重回第一行写入数据
	mov cx,21
	s4:
		mov ax,ds:[di]
		mov ss:[bp+10],ax  ;同上,这个只进行了字型数据操作
		add di,2
		add bp,10h
		loop s4
	
	mov bp,0  					;表行清零,重回第一行写入数据
    mov cx,21 
	s5:    ;公司人均收入=公司总收入/雇员数  ,公司总收入作为被除数是32位的,所以要存放在ax和dx
         ;雇员数为16位,符合div指令公式条件
		mov ax,[bp+5]  		;存放公司总收入的低16位数
		mov dx,[bp+7]  		;存放公司总收入的高16位数
		div word ptr [bp+10]  
		mov [bp+13],ax  	;商存放在ax的位置上,所以写入数据,就用ax
		add bp,10h 
   loop s5  
		
		mov ax,4c00h
		int 21h
codesg ends
end start

4.debug调试

  1. 进行编译

屏幕截图 2023-05-18 213728.png

  1. 进行连接

屏幕截图 2023-05-18 213747.png

  1. 运行

屏幕截图 2023-05-18 214528.png

  1. 先一直按 t ,执行到mov cx,0015,既是源码的 mov cx,21,执行到这里先停一下
  2. 输入r ,查看 ds 、ss 寄存器的内容,得到 DS=076A,SS=0778

屏幕截图 2023-05-18 214659.png

  1. 用 d 076A:0,查看内存单元的内存,即查看data:0 的内存单元内容

屏幕截图 2023-05-18 215741.png

  1. 用 d 0778:0,查看内存单元的内存,即查看table:0 的内存单元内容

微信图片_20230518220109.jpg

  1. 继续t ,遇到 loop ,输入p 跳过
  2. 输入到 mov ax,4c00,停止

屏幕截图 2023-05-18 220238.png

5.实验结果分析

  1. 程序运行完后
  2. 用 d 0778:0,查看table段中的内容

微信图片_20230518220643.jpg

  1. 对比 data:0的数据

屏幕截图 2023-05-18 215741.png

  1. 相差无误,实验成功

6.实验总结和体会

  1. 写一个汇编语言,首先的思路必须弄清楚每个数据的位置,即内存空间地址,这是其他语言没有的
  2. 其次是弄个清楚数据的类型,是字节型、字型还是双字型等等,弄清了数据类型才能更好的使用寄存器
  3. 只有弄清处理数据这两个基本问题,才能开始写汇编语言程序,不然,你更本写不出~

7.程序和源码

程序和源码

### 关于《汇编语言王爽第四版实验资料 对于希望获取《汇编语言王爽第四版中的实验资料或教程,通常这类资源可以通过多种途径获得。书籍本身附带的光盘可能包含了部分实验所需的源代码以及指导文档[^1]。 如果需要更详细的电子版本材料,在合法合规的前提下,可以考虑访问学校图书馆数据库或是通过官方出版社网站查询是否有提供配套的教学资源下载服务。此外,一些在线教育平台也可能提供了基于该教材开发的相关课程,其中会包含完整的实验指南和视频讲解等内容[^2]。 需要注意的是,未经授权私自传播受版权保护的作品属于违法行为,因此建议读者优先选择购买正版图书并利用其自带的学习工具来进行学习活动。 针对具体提到的`ss:[bx]`这种寻址方式的应用场景及其优势在于可以直接操作堆栈段内的数据而无需额外设置寄存器指向目标位置,简化了一定程度上的程序逻辑结构;而在另一个例子中展示了一个简单的字符串拷贝过程,这里涉及到的数据传输是从DS所指明的空间向ES指定的位置逐个搬运字节直到计数器CX减至零为止[^3]。 ```assembly assume cs:code code segment mov ax, source_data_segment ; 将源数据段地址加载到AX mov ds, ax ; 设置DS为源数据段 mov ax, destination_segment; 将目的端地址加载到AX mov es, ax ; ES设为目的段 mov bx, offset_start ; BX初始化偏移量起点 mov cx, length_of_copy ; CX设定需复制长度 s: mov al,[bx] ; 取得当前BX处的一个字符放入AL mov es:[bx],al ; 把这个字符放到由ES定义的目标区相同位移的地方 inc bx ; 增加BX准备处理下一个字符 loop s ; 如果CX不等于0则继续循环 mov ax,4c00h ; 准备退出程序返回操作系统控制 int 21h ; DOS中断调用结束进程 code ends end ; 结束整个代码段描述 ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值