汇编语言 【大练习】寻址方式在结构化访数据访问中的应用
题源:王爽《汇编语言》第八章 实验七
题目要求
汇编易错点
用mov赋值的时候,操作数左右写反,本来想写mov ax,5
却写成mov 5,ax
不看字节长度就直接写入,覆盖后面数据:比如把ax
中的数据写入以byte
形式存储的连续数据区
一些小技巧
当寄存器、段寄存器不够用时,将临时数据存入数据段或栈段中,等需要使用的时候再取出
本题思路
循环嵌套(两层)
外层大循环控制tablesg
段的每一行
内层3个小循环控制分别把年份、收入、雇员数数写入tablesg
段中,3个小循环之后用div
除法指令计算人均收入,也写入tablesg
段中
执行过程截图
debug模式
执行指令之前,内存中初始数据展示:
第一次外循环中,执行完第一个内循环year
第一次外循环中,执行完第二个内循环income
第一次外循环中,执行完第三个内循环income
第一次外循环中,执行完后续除法运算
执行完所有外循环后的结果
执行完毕~
代码
以下可复制
assume cs:codesg,ds:datasg,ds:tablesg,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'
;以上是表示21年的21个字符串 21*4=84个字节 地址(十进制)0~83
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型数据 21*4=84个字节 地址(十进制)84~167
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型数据 21*2=42个字节 地址(十进制)168~209
dw 0,84,168
;临时存储偏移量 210 211 212
datasg ends
tablesg segment
db 21 dup('year summ ne ?? ')
tablesg ends
stacksg segment stack
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;多给了两个
stacksg ends
codesg segment
start:
;ax 临时
;bx 定位tablesg的行
;cx 循环次数
;dx
;ds 存放datasg首地址
;si 利用内存空间的取出和存入,逐字节读取datasg中的:年份\收入\雇员
;datasg首地址放进 段寄存器ds 中
mov ax,datasg
mov ds,ax
;tablesg的首地址放进 段寄存器es 中
mov ax,tablesg
mov es,ax
;bx定位tablesg的行
mov bx,0
;循环21次
mov cx,21
line:
push cx ;cx值存入栈
mov cx,4
mov di,0
year:
mov ax,ds:210 ;从内存中取出si
mov si,ax
mov al,ds:[si] ;ds中年份数据放进al中
mov es:[bx+di],al ;al数据放进tablesg第bx行di位置
inc si
inc di ;si指向下一个
mov ds:210,si ;si存到内存中
loop year
mov di,5 ;4是空格,收入从5开始
mov cx,2
income:
mov ax,ds:212 ;从内存中取出si
mov si,ax
mov ax,ds:[si] ;ds中收入数据放进ax中
mov es:[bx+di],ax ;ax数据放进tablesg第bx行di位置
inc di ;tablesg偏移
inc di
inc si ;datasg偏移
inc si
mov ds:212,si ;si存到内存中
loop income
mov di,10 ;9是空格,雇员从10开始
mov cx,2
people:
mov ax,ds:214 ;从内存中取出si
mov si,ax
mov al,ds:[si] ;ds中雇员数据放进al中
mov es:[bx+di],al ;al数据放进tablesg第bx行di位置
inc si ;si指向下一个
inc di
mov ds:214,si ;si存到内存中
loop people
aver: mov ax,es:[bx+5] ;被除数(收入)4字节=32位,ax存放低16位,从当前行位置5取出
mov dx,es:[bx+7] ;dx存放高16位,从当前行位置7取出
div word ptr es:[bx+10] ;除数(雇员)16位,从当前行位置10取出,与ax,dx中的被除数相除,商存在ax中
mov es:[bx+13],ax ;al商中的商放进当前行位置13处
pop cx ;cx的值pop回去
add bx,10h ;下一行
loop line
mov ax,4c00h
int 21h
codesg ends
end start