王爽 汇编语言个人疑问汇总第四篇
第八章
实验7
Power idea公司从1975年成立一直到1995年的基本情况如下。
原程序
assume cs:code
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年的21个字符串
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型数据
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型数据。
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start:
???????
mov ax,4c00H
int 21H
code ends
end start
程序分析
data数据格式
表格1中1、2行的每个数据占4个字节,第三行数据每个占2个字节。判断多少个字节,参考书上8.8 伪指令dd。
- 可以先加入这2段代码debug下。
...省略...
mov ax,data
mov ds,ax ; 将data段传入ds
... 省略...
第一行偏移地址范围是0H~53H
21 * 4 = 84个字节
最开始我在纠结这个偏移地址为什么是0H ~ 53H,后面我找到别人的答案,debug的时候明白了。
最后一个是1995,占用4个字节,偏移地址可不就是0053H么。
换一个角度算下,每16个字节就要1行的地址,那么这里要5行+4个字节,那偏移地址就是0053H了。
第二行偏移地址范围是54H~0a7H
这里也是 21 * 4 = 84 个字节
在0053H基础上往后推84个字节
第三行偏移地址范围是a8H~00d1H
21 * 2 = 42个字节
在0a7H基础上往后42个字节
偏移地址截止到00D1H
修改后的程序
- 注意:只要我们把 “year summ ne ?? ”覆盖掉,就刚好是我们要的格式。
;16 * 4 = 64 + 8 = 72 + 12 =
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年的21个字符串
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型数据
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型数据
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
codesg segment
start: mov ax,data
mov ds,ax ; 将data段传入ds
mov ax,table
mov es,ax ; 将table段传入es
mov bx,0
mov si,0
mov di,0
mov cx,15H ; 循环次数,15H也就是21
s: mov ax,ds:[bx] ; 将年份低位传入ax寄存器
mov es:[si],ax ; 将ax中的年份低位传入es:[si]的0位
mov ax,ds:[bx + 2] ; 将年份高位传入ax寄存器
mov es:[si + 2],ax ; 将ax中的年份高位传入es:[si]的2位
; 以上四条指令处理表格此行的年份
mov ax,ds:[bx + 54h] ; 将收入低位传入ax寄存器
mov es:[si + 5],ax ; 将ax中的收入低位传入es:[si]的5位
mov ax,ds:[bx + 56h] ; 将收入高位传入ax寄存器
mov es:[si + 7],ax ; 将ax中的收入高位传入es:[si]的7位
; 以上四条指令处理表格此行的收入
mov ax,ds:[di + 00a8h] ; 将雇员数传入ax寄存器
mov es:[si + 0ah],ax ; 将雇员数传入es:[si]的10位
; 以上两条指令处理表格此行的雇员数
mov ax,[bx + 54h] ; 取收入的低16位传入ax
mov dx,[bx + 56h] ; 取收入的高16位传入dx
div word ptr es:[si + 0ah] ; 收入除以雇员数,用ax:dx中的32位数据除以es:[si + 0ah]中的数据
mov es:[si + 0dh],ax ; 将ax中收入的整数传入es:[si]的13位
; 以上四条指令处理表格此行的人均收入
add si,16 ; 表格换行
add di,2 ; 雇员数和人均收入均为2字节
add bx,4 ; 年份和收入均为4字节
loop s ; 循环
mov ax, 4c00h
int 21h
codesg ends
end start
运行结果
本题参考
https://www.jianshu.com/p/c59ebcba1536
https://www.cnblogs.com/Base-Of-Practice/articles/6883907.html
https://blog.csdn.net/weixin_42553435/article/details/80863344