实验7详解最佳方案
从昨晚到今晚,画了几满页的图纸,终于搞定这个程序了。初学者,自认为最优代码。如有不对之处,请高手指出。
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个字符串(dword型数据)(21*4个字节)
dd 000016,000022,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个字节)
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,45257,17800
;以上是表示21年公司雇员人数的21个word型数据(21*2个字节)
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 ss,ax ;定位[表格]为栈段
sub bx,bx ;初始化[数据]行数
sub si,si ;初始化[雇员]行数
sub bp,bp ;初始化[表格]行数
sub di,di
mov cx,21 ;处理21行数据
s: mov ax, ;读取[数据]中[年份列]低16位到ax
mov dx, ;读取[数据]中[年份列]高16位到dx
mov ,ax ;将ax写入到[表格]中[年份列]低16位
mov ,dx ;将dx写入到[表格]中[年份列]高16位
mov ax, ;读取[数据]中[收入列]低16位到ax
mov dx, ;读取[数据]中[收入列]高16位到dx
mov ,ax ;将ax写入到[表格]中[收入列]低16位
mov ,dx ;将dx写入到[表格]中[收入列]高16位
mov di, ;读取[雇员数列]到di
mov ,di ;将di写入到[表格]中[雇员数列]
div di ;运算[人均收入]
mov ,ax ;将结果保存到bp行[人均收入]列中
add bx,4 ;[数据]进入下一行(每行相差4个字节)
add si,2 ;[雇员]进入下一行每行相差2个字节
add bp,16 ;[表格]进入下一行(每行相差16个字节)
loop s
over: mov ax,4c00h ;程序出口
int 21h
codesg ends
end start sub bx,bx ;初始化[数据]行数
sub si,si ;初始化[雇员]行数
sub bp,bp ;初始化[表格]行数
sub di,di
这几句是不是想要将这几个寄存器清零?如果清零的话,推荐使用xor指令!!
其次,你代码中没有对这类mov ax,操作指定段寄存器,应该写成‘mov ax,ds:’,这还不是重要的,重要的是,“mov ,ax ”这些一定要指定段寄存器,应该写成“mov ss:,ax ”,否则,会默认成mov ds:,ax
暂时就这么多! 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个字符串(dword型数据)(21*4个字节)
dd 000016,000022,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个字节)
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,45257,17800
;以上是表示21年公司雇员人数的21个word型数据(21*2个字节)
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,168 ;单独指向雇员人数 ,如果你这里不这样指定,你下面的bx加2没有意义
xor si,si ;ds:指向数据 汇编中一般将取数据的地址用si指向
xor di,di ;es:指向表格 汇编中一般将存数据的地址用di指向
xor bp,bp ;下面单独用作除数
mov cx,21 ;处理21行数据
s: mov ax,[si] ;读取[数据]中[年份列]低16位到ax
mov es:[di],ax ;将ax写入到[表格]中[年份列]低16位 这里你不指定段寄存器的话,会默认段寄存器为ds的,如果这样就跟你的想法相悖了,下面也是如此
mov ax,[si+2] ;读取[数据]中[年份列]高16位到dx
mov es:[di+2],dx ;将dx写入到[表格]中[年份列]高16位
mov ax, ;读取[数据]中[收入列]低16位到ax
mov es:,ax ;将ax写入到[表格]中[收入列]低16位
mov dx, ;读取[数据]中[收入列]高16位到dx
mov es:,dx ;将dx写入到[表格]中[收入列]高16位
mov bp, ;读取[雇员数列]到di
mov es:,bp ;将di写入到[表格]中[雇员数列]
div bp ;运算[人均收入] 这里用bp做除数,这个到是没有规定必须那个寄存器做除数,只要跟存放被除数的ax,dx不冲突就行
mov es:,ax ;将结果保存到bp行[人均收入]列中
add si,4 ;[数据]进入下一行(每行相差4个字节)
add bx,2 ;[雇员]进入下一行每行相差2个字节
add di,16 ;[表格]进入下一行(每行相差16个字节)
loop s
mov ax,4c00h ;程序出口
int 21h
codesg ends
end start
以上是我帮你修改的,红字是修改的地方!!!
xiaolongxia 发表于 2012-6-1 00:03 static/image/common/back.gif
assume cs:codesg
data segment ;[数据]
多谢楼上两位达人,本人初学者,教程刚看完第8章。还没接触到xor指令。。。
我是自己独立完成的,并非copy小甲鱼的答案,不过对比了一下,发现他的思路跟我是差不多的。。。
或许这就是最佳答案了吧~
2楼。据我所知,默认在ds段中。默认在ss段中吧?这也正是我用ds+bx,ss+bp的原因。
请注意,我是用ss,而不是es。
因为一开始的思路是想push进去。自定义sp的值。结果发现无法实现。。。
3楼。注意我的0a8h换成10进制便是168了
经过测试,程序未出现任何问题。 {:5_109:}也对,不好意思,都忘了,一直在32位下写东西,16位的东西有些遗忘了,没错就行!程序正常运行就行!我提供的也算是一种思路吧,di,si常用的方法!呵呵
页:
[1]