1.实验内容
实验内容为将 data 段中的数据按照表格的形式写入到 table 段中,并计算 21 年中的人均收入
2.前置知识
- 1个字节---->占一个内存空间
- 1个字---->占两个内存空间
- 1个双字节---->占四个个内存空间
- dd 16 中 16 是十进制数,转为 debug 中就是 00000010,一共八位16进制数,占四个字节
- dw 16 在 debug 中就是 0010,一共四位16进制数,占两个字节
3.实验过程
-
实验思路
-
首先看 data 段中的各个数据的位置,大概算出每个数据的内存空间地址
-
其次看 table 段表中的各个数据的内存空间地址
-
在想各个寄存器有什么用
- cs:存放代码段地址
- ds:存放 data 段中数据的段地址
- ss:存放 table 段中数据的段地址
- ax:传输数据用、做除法用
- di:用于记 data 中的数据位置
- bp:用于记 table 的行
- si:用于记 table 的列
-
最后开始操作
-
先把年份写进去表中
-
把总收入写进表中
-
把公司雇员人数写进表中
-
最后计算公司人均收入
-
-
代码和注释如下
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调试
- 进行编译
- 进行连接
- 运行
- 先一直按 t ,执行到mov cx,0015,既是源码的 mov cx,21,执行到这里先停一下
- 输入r ,查看 ds 、ss 寄存器的内容,得到 DS=076A,SS=0778
- 用 d 076A:0,查看内存单元的内存,即查看data:0 的内存单元内容
- 用 d 0778:0,查看内存单元的内存,即查看table:0 的内存单元内容
- 继续t ,遇到 loop ,输入p 跳过
- 输入到 mov ax,4c00,停止
5.实验结果分析
- 程序运行完后
- 用 d 0778:0,查看table段中的内容
- 对比 data:0的数据
- 相差无误,实验成功
6.实验总结和体会
- 写一个汇编语言,首先的思路必须弄清楚每个数据的位置,即内存空间地址,这是其他语言没有的
- 其次是弄个清楚数据的类型,是字节型、字型还是双字型等等,弄清了数据类型才能更好的使用寄存器
- 只有弄清处理数据这两个基本问题,才能开始写汇编语言程序,不然,你更本写不出~