|
主题 : : 绝了!比置顶程序还要牛的程序,不另外定义段,只用23条汇编指令完成程序要求。比最牛程序少用了七行代码。 [待解决] |
回复[ 66次 ]
点击[ 6547次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2009-07-02 10:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-09-26 07:46 |
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov si,0a8h
mov ax,table
mov ss,ax
mov bp,0
mov cx,21
s:mov ax,[si]
mov [bp+0ah],ax
mov ax,[bx]
mov dx,{bx+2}
mov [bp],ax
mov [bp+2],dx
mov ax,[54h+bx]
mov dx,[56h+bx]
mov [bp+05h],ax
mov [bp+07h],dx
div word ptr [bp+0ah]
mov [bp+0dh],ax
add bx,4
add si,2
add bp,10h
loop s
mov ax,4c00h
int 21h
code ends
end start
我的QQ:479488993 我的博客:http://www.asmedu.net/blog/user/usermain.jsp?neighborId=14266 希望与热爱技术的人为伍。 | | |
|
|
|
|
[第1楼]
[ 回复时间:2009-07-02 14:04 ]
[引用]
[回复]
[ top ] | |
荣誉值:33
信誉值:0
注册日期:2008-10-16 10:01 |
|
|
|
|
|
[第2楼]
[ 回复时间:2009-07-13 14:22 ]
[引用]
[回复]
[ top ] | |
荣誉值:1
信誉值:8
注册日期:2009-06-27 18:30 |
讨厌,刚才在一博客上看到这段代码,着实佩服了一番.原来,他是抄你的.真是的.不劳而获. | | |
|
|
|
|
[第3楼]
[ 回复时间:2009-07-26 00:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-07-10 14:13 |
assume cs:codesg,ds:data,es: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 ?? ')
table ends
codesg segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov si,0
mov di,0
mov cx,21
s:mov ax,[bx]
mov es:[si],ax
mov ax,[bx+2]
mov es:[si+2],ax
mov ax,[di+168]
mov es:[si+10],di
mov ax,[bx+84]
mov es:[si+5]
mov dx,[bx+86]
mov es:[si+7]
div word prt es:[si+10]
mov es:[si+13],ax
add bx,4
add si,16
inc di
inc di
loop s
mov ax,4c00h
int 21h
codesg ends
这段谁给看看 | | |
|
|
|
|
[第4楼]
[ 回复时间:2009-10-16 19:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-09 19:25 |
|
|
|
|
|
[第5楼]
[ 回复时间:2009-10-16 19:22 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-09 19:25 |
|
|
|
|
|
[第6楼]
[ 回复时间:2009-11-24 17:10 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-11-20 13:32 |
这段不是更简单吗?还要用div吗
codesg segment
start:mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov cx,21
mov bx,0
mov si,0
mov di,0
s:mov ax,ds:0[si] ;copy year
mov es:0[bx],ax
mov ax,ds:0[si+2]
mov es:0[bx+2],ax
mov ax,ds:84[si] ;copy sum input
mov es:5[bx],ax
mov ax,ds:84[si+2]
mov es:5[bx+2],ax
mov ax,ds:168[di] ;copy employee sum
mov es:10[bx],ax
add si,4
add di,2
add bx,16
loop s
mov ax,4c00h
int 21h
codesg ends | | |
|
|
|
|
[第7楼]
[ 回复时间:2009-11-24 17:55 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-11-20 13:32 |
codesg segment
start:mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov cx,21
mov bx,0
mov si,0
mov di,0
s:mov ax,ds:0[si] ;copy year
mov es:0[bx],ax
mov ax,ds:0[si+2]
mov es:0[bx+2],ax
mov ax,ds:84[si] ;copy sum input
mov es:5[bx],ax
mov dx,ds:84[si+2]
mov es:5[bx+2],dx
mov ax,ds:168[di] ;copy employee sum
mov es:10[bx],ax
div word ptr es:10[bx] ; copy average
add si,4
add di,2
add bx,16
loop s
mov ax,4c00h
int 21h
codesg ends | | |
|
|
|
|
[第8楼]
[ 回复时间:2009-12-18 21:07 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-12-18 14:37 |
start:
mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov cx,21
mov si,0
mov di,0
s:
mov ax,[si]
mov es:[bx],ax
mov ax,[si+2]
mov es:[bx+2],ax
mov ax,[di+168]
mov es:[bx+10],ax
mov ax,[si+84]
mov es:[bx+5],ax
mov dx,[si+86]
mov es:[bx+7],dx
div word ptr [di+168]
mov es:[bx+13],ax
add si,4
add di,2
add bx,16
loop s
mov ax,4c00h
int 21h
codesg ends
end start
学了两天编出来的程序,大家看下 | | |
|
|
|
|
[第9楼]
[ 回复时间:2010-01-14 22:59 ]
[引用]
[回复]
[ top ] | |
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51 |
顶楼上的, 学两天就可以写出这么漂亮的代码。。。羡慕。 | | |
|
|
|
|
[第10楼]
[ 回复时间:2010-03-19 15:48 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-11-16 13:00 |
|
|
|
|
|
[第11楼]
[ 回复时间:2010-03-27 18:34 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2009-07-15 11:17 |
8楼好强啊,我自己虽然也写出这个程序了,但是效率不如你的。 | | |
|
|
|
|
[第12楼]
[ 回复时间:2010-05-18 13:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-05-18 12:52 |
|
|
|
|
|
[第13楼]
[ 回复时间:2010-06-04 17:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-05-28 23:02 |
8楼的2天就那么牛了,我无地自容了,在给你几天中国就该出自己的系统了,有希望 | | |
|
|
|
|
[第14楼]
[ 回复时间:2010-07-17 19:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-12 14:54 |
嘿嘿~我写的和8楼的兄弟的几乎一样~但我已经学了7,8天了~!! | | |
|
|
|
|
[第15楼]
[ 回复时间:2010-07-17 22:34 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2010-07-13 10:33 |
汗~八楼的“两”是确数还是约数……【别怪我,老师说……要严谨…… | | |
|
|
|
|
[第16楼]
[ 回复时间:2010-07-22 21:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-22 20:52 |
为了说说我的看法只好注册个号了。。。
楼主的有一行代码错了, mov dx,{bx+2} 应该是mov dx,[bx+2]
不过这个不是大问题,我觉得最不好的地方是你用了SS,也就是把默认的堆栈当普通数据寄存用了,感觉不规范。。。
3楼的思路是对的,可惜基本功。。。竟然写出了mov es:[si+5] 这样的句子,后边的,ax呢?所以要多写多练习,尤其是你没有注释和分段,这样的程序大了之后很难读
6楼的没用div就做出来了让我惊讶,很仔细地看完,发现你没看清题目,请继续审题。。。
7楼的不知道你们试了没有,肯定出问题,因为他把收入跟员工数的顺序弄反了,估计是学习了那个很多push例子的某位牛人的思路,可惜没有深刻理解为什么那位牛人没有用ax而用了dx做传递,不过只要把顺序调过来就是这个版最好的源码
8楼的没话说,确实很好,除了结构和注释上应该努力,养成好习惯,其他perfect,尤其是学了2天写出来的,很强大。。。
assume cs:code, ds:data, es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982'
db '1983','1984','1985','1986','1987','1988','1989','1990'
db '1991','1992','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个双字型数据
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个字型数据
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,table
mov es,ax ;初始化数据和表格段地址
mov bx,0
mov si,0
mov di,0 ;初始化偏移量,bx是表格行偏移,si是年份字偏移,di是年份双字偏移
mov cx,21 ;初始化循环计数器
s:
mov ax,[di+0]
mov es:[bx],ax
mov ax,[di+2]
mov es:[bx+2],ax ;对年份的处理
mov ax,168[si]
mov es:[bx+10],ax ;对雇员的处理
mov ax,84[di]
mov es:[bx+5],ax
mov dx,86[di]
mov es:[bx+7],dx ;对总收入的处理,使用dx是因为不用重复赋值
div word ptr es:[bx+10]
mov es:[bx+13],ax ;对平均收入的处理
add si,2
add bx,16
add di,4 ;偏移量增值
loop s
mov ax,4c00h
int 21h
code ends
end start
这个是我写的,第一次写的没这么好,吸收了很多牛人的例子相信是不用push里最好的之一了。。。 | | |
|
|
|
|
[第17楼]
[ 回复时间:2010-07-30 18:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:8
信誉值:0
注册日期:2010-07-12 08:47 |
楼上的,你的dx应该先初始化一下吧。直接用虽然可以但好像不妥。 | | |
|
|
|
|
[第18楼]
[ 回复时间:2010-08-06 06:33 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:0
注册日期:2010-07-25 14:15 |
|
|
|
|
|
[第19楼]
[ 回复时间:2010-09-12 19:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-09-03 12:12 |
|
|
|
|
|
[第20楼]
[ 回复时间:2010-10-09 17:48 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-09 17:39 |
|
|
|
|
|
[第21楼]
[ 回复时间:2010-10-14 22:44 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-12 21:57 |
|
|
|
|
|
[第22楼]
[ 回复时间:2010-10-30 21:14 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-13 21:26 |
|
|
|
|
|
[第23楼]
[ 回复时间:2010-11-05 22:08 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-21 13:38 |
今天看的头痛,这个帖子导致我吐了,不是恶心各位,别误会。 | | |
|
|
|
|
[第24楼]
[ 回复时间:2010-11-20 11:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-11-19 22:48 |
十六楼的dx应该赋值总收入的高位吧,你赋值的是低位呀
mov ax,84[di]
mov es:[bx+5],ax
mov dx,86[di]
mov es:[bx+7],dx ;对总收入的处理,使用dx是因为不用重复赋值
应该这样写吧:
mov dx,84[di]
mov es:[bx+5],dx
mov ax,86[di]
mov es:[bx+7],ax
欢迎讨论交流 | | |
|
|
|
|
[第25楼]
[ 回复时间:2010-11-20 11:43 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-11-19 22:48 |
十六楼的dx应该赋值总收入的高位吧,你赋值的是低位呀
mov ax,84[di]
mov es:[bx+5],ax
mov dx,86[di]
mov es:[bx+7],dx ;对总收入的处理,使用dx是因为不用重复赋值
应该这样写吧:
mov dx,84[di]
mov es:[bx+5],dx
mov ax,86[di]
mov es:[bx+7],ax
欢迎讨论交流
------------------
回复:24楼的同学忘了内存单元高位地位的存放顺序了,惭愧。。 | | |
|
|
|
|
[第26楼]
[ 回复时间:2010-12-04 21:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-04 20:54 |
哎!大意了,闭门造车N个月,原来这里有这么多高手,多好的资源啊,这个程序我也写出来了,用了N个loop,还沾沾自喜,惭愧啊!!! 多谢楼主,也多谢各楼兄弟!往后多指教! | | |
|
|
|
|
[第27楼]
[ 回复时间:2010-12-07 18:49 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-04 20:54 |
8楼写的确实好,我给加了注释
codesg segment
start:
mov ax,data
mov ds,ax ;用ds指向data 段
mov ax,table
mov es,ax ;用es指向table段
mov bx,0 ;初始化各数据指针
mov si,0
mov di,0
mov cx,21 ;设置循环次数
s:
mov ax,[si] ;复制年份
mov es:[bx],ax
mov ax,[si+2]
mov es:[bx+2],ax
mov ax,[di+168] ;复制员工数
mov es:[bx+10],ax
mov ax,[si+84] ;复制年总收入,使用dx方便人均收入的计算
mov es:[bx+5],ax
mov dx,[si+86]
mov es:[bx+7],dx
div word ptr [di+168] ;计算人均收入
mov es:[bx+13],ax ;写入人均收入
add si,4 ;准备下一次循环的数据指针
add di,2
add bx,16
loop s ;精妙之处在于作者在1.复制年份和总收入时,各用了两个常数(0,2和84,86)作为数据指针
;2.先复制员工数,这极大的方便了人均收入的计算。
mov ax,4c00h
int 21h
codesg ends
end start | | |
|
|
|
|
[第28楼]
[ 回复时间:2010-12-14 11:39 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-05 15:22 |
7楼才牛逼。。。看了7楼可以真正体会到数组和结构体的精髓。
其他的勉强吧 | | |
|
|
|
|
[第29楼]
[ 回复时间:2010-12-14 11:49 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-05 15:22 |
1.慢慢体会数组:
0[si],0[si+2];
84[si],84[si+2];
168[di];
这是数据源的三个数组。这样写才有数组a[N]的味道。
2.慢慢体会结构体:
es:[bx].0[0],es:[bx].0[2];
es:[bx].5[0],es:[bx].5[2];
es:[bx].10,
es:[bx].0dH | | |
|
|
|
|
[第30楼]
[ 回复时间:2010-12-14 12:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-12-05 15:22 |
改进7楼的。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个字符串
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,45257,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
mov ax,table
mov es,ax
mov cx,21
mov bx,0
mov si,0
mov di,0
s:mov ax,ds:0[si] ;copy year
mov es:[bx].0,ax
mov ax,ds:0[si+2]
mov es:[bx].0[2],ax
mov ax,ds:84[si] ;copy sum input
mov es:[bx].5,ax
mov dx,ds:84[si+2]
mov es:[bx].5[2],dx
mov ax,ds:168[di] ;copy employee sum
mov es:[bx].10,ax
div word ptr es:10[bx] ; copy average
mov es:[bx].0dh,ax
add si,4
add di,2
add bx,16
loop s
mov ax,4c00h
int 21h
codesg ends
end start | | |
|
|
|
|
[第31楼]
[ 回复时间:2010-12-23 14:24 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-21 15:56 |
其实 我在怀疑你们到底有没有调试过。
程序运行完全不对头。 | | |
|
|
|
|
[第32楼]
[ 回复时间:2010-12-26 17:40 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-10-06 11:12 |
|
|
|
|
|
[第33楼]
[ 回复时间:2011-02-12 20:55 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:4
注册日期:2011-01-29 19:28 |
回复:[第29楼]
------------------
请恕我眼拙,实在没看出这有什么精妙之处,没有任何瞧不起的意思,只是想要问问,这样写有什么
好处,个人感觉只是不同的寻址方式,有什么区别吗?
谢谢,才学编程没几天,C语言也只是刚看到数组,指针那块。
谢谢 | | |
|
|
|
|
[第34楼]
[ 回复时间:2011-02-20 01:53 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-02-02 04:30 |
其实 我在怀疑你们到底有没有调试过。
程序运行完全不对头。
------------------
回复:是啊??? | | |
|
|
|
|
[第35楼]
[ 回复时间:2011-03-07 02:46 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:0
注册日期:2009-12-03 21:13 |
assume cs:code,ds:data,ss:stack
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 11542,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
stack segment
dw 8 dup (0)
stack ends
code segment
start : mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,16
mov ax,table
mov es,ax
mov bx,0 ;为年份和收入的地址变量?每次loop加4字节
mov si,0 ;为table表变量,每次loop加16字节
mov di,168 ;为人数地址变量,每次loop加2字节
mov cx,21
s:push cx ;后面有用到cx当除数所以在这保存
mov ax,[bx] ;输入年份
mov es:[si],ax
mov ax,2[bx]
mov es:2[si],ax
mov byte ptr es:4[si],' ' ;空格
mov ax,[bx+84] ;输入收入
mov es:5[si],ax
mov dx,2[bx+84] ;这里用dx因为后面当作被除数的高位
mov es:7[si],dx
mov byte ptr es:9[si],' '
mov cx,[di] ;输入人数,用CX因为当作除数
mov es:10[si],cx
mov byte ptr es:12[si],' '
div cx ;收入除以人数
mov es:13[si],ax
mov byte ptr es:15[si],' '
add si,16
add bx,4
add di,2
pop cx
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第36楼]
[ 回复时间:2011-03-07 02:48 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:0
注册日期:2009-12-03 21:13 |
-d 0b61:0 14f
0B61:0000 31 39 37 35 20 10 00 00-00 20 03 00 20 05 00 20 1975 .... .. ..
0B61:0010 31 39 37 36 20 16 00 00-00 20 07 00 20 03 00 20 1976 .... .. ..
0B61:0020 31 39 37 37 20 7E 01 00-00 20 09 00 20 2A 00 20 1977 ~... .. *.
0B61:0030 31 39 37 38 20 4C 05 00-00 20 0D 00 20 68 00 20 1978 L... .. h.
0B61:0040 31 39 37 39 20 56 09 00-00 20 1C 00 20 55 00 20 1979 V... .. U.
0B61:0050 31 39 38 30 20 40 1F 00-00 20 26 00 20 D2 00 20 1980 @... &. ..
0B61:0060 31 39 38 31 20 80 3E 00-00 20 82 00 20 7B 00 20 1981 .>.. .. {.
0B61:0070 31 39 38 32 20 A6 5F 00-00 20 DC 00 20 6F 00 20 1982 ._.. .. o.
0B61:0080 31 39 38 33 20 91 C3 00-00 20 DC 01 20 69 00 20 1983 .... .. i.
0B61:0090 31 39 38 34 20 C7 7C 01-00 20 0A 03 20 7D 00 20 1984 .|.. .. }.
0B61:00A0 31 39 38 35 20 81 24 02-00 20 E9 03 20 8C 00 20 1985 .$.. .. ..
0B61:00B0 31 39 38 36 20 8A 03 03-00 20 A2 05 20 88 00 20 1986 .... .. ..
0B61:00C0 31 39 38 37 20 7C 47 05-00 20 D2 08 20 99 00 20 1987 |G.. .. ..
0B61:00D0 31 39 38 38 20 EB 03 09-00 20 E9 0A 20 D3 00 20 1988 .... .. ..
0B61:00E0 31 39 38 39 20 CA 42 0C-00 20 C5 0F 20 C7 00 20 1989 .B.. .. ..
0B61:00F0 31 39 39 30 20 18 0D 12-00 20 03 16 20 D1 00 20 1990 .... .. ..
0B61:0100 31 39 39 31 20 38 1F 1C-00 20 22 20 20 E0 00 20 1991 8... " ..
0B61:0110 31 39 39 32 20 58 19 2A-00 20 16 2D 20 EF 00 20 1992 X.*. .- ..
0B61:0120 31 39 39 33 20 28 44 39-00 20 5E 38 20 04 01 20 1993 (D9. ^8 ..
0B61:0130 31 39 39 34 20 28 F0 46-00 20 99 3B 20 30 01 20 1994 (.F. .; 0.
0B61:0140 31 39 39 35 20 68 97 5A-00 20 88 45 20 4D 01 20 1995 h.Z. .E M. | | |
|
|
|
|
[第37楼]
[ 回复时间:2011-03-12 20:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-15 22:31 |
|
|
|
|
|
[第38楼]
[ 回复时间:2011-03-16 04:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-26 21:21 |
。。。。。八楼基础好,之前肯定学过C语言或者其他的,不可能白手起家两天弄出个来 | | |
|
|
|
|
[第39楼]
[ 回复时间:2011-03-22 01:41 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-03-19 14:07 |
|
|
|
|
|
[第40楼]
[ 回复时间:2011-04-06 10:13 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-05 23:23 |
现代的程序,代码的可读性远比代码的行数更重要,用代码行数来评价程序的好坏实在是很无聊的事情
楼主的代码还是有些可取之处的,和其他人不同的是他用到了bp,这可以少敲不少字符,我的感觉是,在所有的寻址方式中,只有bx和bp这两个寄存器是最灵活的,应该好好利用,而且在本题后面的提示中也说到,推荐用bx来表示目的地址,所以用bx应该是没问题的,但是是否用bp可能还是有争议,最主要得是因为原题中出题时就直接写es:table了,如果从题目的角度考虑,用bp是有些跑题了,但是从实践的角度来看,用ss和bp应该更好一些,其它的实现大家做得其实都差不多,彼此借鉴一下也好,附上我的本题代码:
assume cs:codesg,ds:data,ss:table
data segment
;年份的21个字符串
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个双字型数据
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;公司雇员人数的21个字型数据
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 ?? ')
table ends
codesg segment
start:
;初始化数据和表格段地址
mov ax, data
mov ss, ax
mov ax, table
mov ds, ax
; 初始化数据,bp是源地址偏移量,di是dd偏移量(每次+4),si是dw偏移量(每次+2),bx是目的地址偏移量(每次+16)
mov bp, 0
mov bx, 0
mov si, 0
mov di, 0
;初始化循环变量
mov cx, 21
s:
; 填充年份
mov ax, [bp+di]
mov [bx], ax
mov ax, [bp+di+2]
mov [bx+2], ax
; 填充人数
mov ax, [bp+168+si]
mov [bx+10], ax
; 填充收入,这里直接使用了ax,dx是为了div做准备
mov ax, [bp+84+di]
mov [bx+5], ax
mov dx, [bp+84+di+2]
mov [bx+5+2], dx
; 计算平均值
div word ptr [bp+168+si]
mov [bx+13], ax
add di, 4
add si, 2
add bx, 16
loop s
mov ax, 4c00H
int 21H
codesg ends
end start
简单调试结果:
-g 0048
AX=014D BX=0150 CX=0000 DX=2580 SP=0000 BP=0000 SI=002A DI=0054
DS=14DA ES=14BC SS=14CC CS=14EF IP=0048 NV UP EI PL NZ NA PE NC
14EF:0048 B8004C MOV AX,4C00
-d ds:0
14DA:0000 31 39 37 35 20 10 00 00-00 20 03 00 20 05 00 20 1975 .... .. ..
14DA:0010 31 39 37 36 20 16 00 00-00 20 07 00 20 03 00 20 1976 .... .. ..
14DA:0020 31 39 37 37 20 7E 01 00-00 20 09 00 20 2A 00 20 1977 ~... .. *.
14DA:0030 31 39 37 38 20 4C 05 00-00 20 0D 00 20 68 00 20 1978 L... .. h.
14DA:0040 31 39 37 39 20 56 09 00-00 20 1C 00 20 55 00 20 1979 V... .. U.
14DA:0050 31 39 38 30 20 40 1F 00-00 20 26 00 20 D2 00 20 1980 @... &. ..
14DA:0060 31 39 38 31 20 80 3E 00-00 20 82 00 20 7B 00 20 1981 .>.. .. {.
14DA:0070 31 39 38 32 20 A6 5F 00-00 20 DC 00 20 6F 00 20 1982 ._.. .. o. | | |
|
|
|
|
[第41楼]
[ 回复时间:2011-04-07 13:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-04 12:01 |
不知道为什么我调试他们的程序,除了40楼的正常,年份输出都有问题。都显示不全,不知各位有没有出现这种状况? | | |
|
|
|
|
[第42楼]
[ 回复时间:2011-04-16 19:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-15 22:31 |
一楼 我跟踪了你的程序 复制的只是 19 没别的了 | | |
|
|
|
|
[第43楼]
[ 回复时间:2011-04-16 21:09 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-01-15 22:31 |
assume cs:Code
data segment
db '1975','1976','1977','1978','1979','1980','1981'
db '1982','1983','1984','1985','1986','1987','1988'
db '1989','1990','1991','1992','1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479
dd 140417,197514,345980,590827,803530,118300,1843000
dd 2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037
dw 5635,8226,11542,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start:mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov si,0
mov di,0
mov bp,0
mov cx,21
s: mov ax,[bx+si]
mov es:[bp],ax
mov ax,[bx+si+56h] //记住 dd第一个是16对吧 在bebug里面显示的是10000000 看清楚 补码在后面补的
mov dx,ax//先将 高位服入DX
mov es:[bp+7],dx
mov ax,[bx+di+0a8h]
mov es:[bp+0ah],ax
mov ax,[bx+si+2]
mov es:[bp+2],ax
mov ax,[bx+si+54h]
mov es:[bp+5],ax
div word ptr es:[bp+0ah]
mov es:[bp+0dh],ax
add si,4
add di,2
add bp,16
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第44楼]
[ 回复时间:2011-10-05 16:31 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:2
注册日期:2010-11-24 11:04 |
; 实验7
assume cs:codereg,ds:datareg
datareg segment
; 21年的21个字符串
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型数据
dd 16,22,382,1356,2390,8000,76000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
; 21年公司雇员人数的21个word型数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2558,2793,4037,5635,8226
dw 11542,14430,15257,17800
datareg ends
table segment
db 21 dup('year summ ne ?? ') ; 21 * 16
table ends
codereg segment
start: mov ax,datareg
mov ds,ax
mov ax,table
mov ss,ax
mov bx,0 ; 数据段起始偏移地址
mov si,168 ; 雇员数据偏移量
mov bp,0 ; table段偏移地址,bp为偏移地址默认段地址为ss
mov cx,21
s: mov ax,[bx] ; 复制年份数据
mov [bp],ax
mov ax,[bx + 2]
mov [bp + 2],ax
mov ax,[bx + 84]; 复制收入数据
mov [bp + 5],ax
mov dx,[bx + 86]
mov [bp + 7],dx
mov di,[si] ; 复制雇员人数
mov [bp + 10],di
div di ; 计算平均值并复制商到table
mov [bp + 13],ax
add bx,4
add si,2
add bp,10
loop s
mov ax,4C00H
int 21H
codereg ends
end start | | |
|
|
|
|
[第45楼]
[ 回复时间:2013-12-21 17:43 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:6
注册日期:2009-07-15 11:17 |
16楼的程序对这道题来说,确实很好。
不过我个人觉得,这样的代码结构性和可读性都很差,比如说从结构化设计程序的角度来说,按顺序,最好先处理“收入”数据,再处理“雇员数”数据,不然要处理的数据类型如果很多的话,打乱顺序以后程序的结构就显得混乱。
另外,SI寄存器是(Source Index)的缩写,DI寄存器是(Destination Index)的缩写,SI一般是用来访问“源数据”的,DI一般是用来访问“目标数据”的,16楼的程序把SI和DI都用来访问“源数据”,显得混乱,如果程序稍微复杂那么一点点,比如说再定义1个段,以3个字节存储公司每年的排名,这种方法就不行了。从结构化的角度来说,不如多用几个循环,使程序变得清晰。 | | |
|
|
|
|
[第46楼]
[ 回复时间:2014-09-02 22:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2014-08-29 19:48 |
那是因为mov dx,{bx+2} 这行写成大括号了。 | | |
|
|
|
|
[第47楼]
[ 回复时间:2015-06-02 20:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-05-19 20:56 |
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'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,469000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov cx,21
mov si,0
mov di,0
s: mov ax,[si]
mov dx,[si+2]
mov es:[bx],ax
mov es:[bx+2],dx
mov dx,[di+0a8h]
mov es:[bx+0ah],dx
mov ax,[si+54h]
mov dx,[si+56h]
mov es:[bx+5h],ax
mov es:[bx+7h],dx
div word ptr [di+0a8h]
mov es:[bx+0dh],ax
add di,2
add si,4
add bx,10h
loop s
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第48楼]
[ 回复时间:2015-06-05 20:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-06-02 09:14 |
我写的这个与上面的不同点在于按顺序写入: 年份、收入、雇员、人均收入,所以多使用了一个si寄存器,25行代码。
好处就是直观,另一个就是有注释,可以很方便的查看。建议要多写精简的注释,方便别人和自己理解,多年后再看不费劲。
上面其他的写入顺序是:年份、雇员、收入、人均收入,那么就会少用一个寄存器,24行代码。
codesg segment
start: mov ax,table
mov ds,ax; ds指向table段
mov ax,data
mov ss,ax; ss段使用数据
mov bx,0; ds:[bx].idata 数组表示法,修改表格
mov bp,0; ss:[bp].idata 数组表示法,获取数据
mov si,0; si存雇员数占用空间2 bytes大小
mov di,0; di用于除法
mov cx,21; 循环次数,21个年份
s: ;年份
mov ax,[bp]
mov [bx].00h,ax; 写入年份低两位
mov ax,[bp].02h
mov [bx].02h,ax; 写入年份高两位
;收入
mov ax,[84+bp]
mov [bx].05h,ax; 写入收入低两位
mov dx,[84+bp].02h
mov [bx].07h,dx; 写入收入低两位
;雇员
mov di,ss:[168+si]
mov [bx].0Ah,di; 写入雇员数量
;人均收入
div di; 被除数dx和ax,除数di
mov [bx].0Dh,ax; 余数在ax,写入人均收入
add bx,16; 跳到表格下一行
add bp,4; 年份和收入跳跃间隔
add si,2; 雇员数跳跃间隔
loop s
mov ax,4c00h
int 21h
codesg ends | | |
|
|
|
|
[第49楼]
[ 回复时间:2015-06-21 11:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-06-19 10:06 |
To 7楼 和 30楼:
你们的代码是有问题的:在算平均收入那个地方,你们的代码中,AX中的值已经不是总收入的低16位了,而这里被除数是32位,要求低16位在AX中,高16位在DX中。 | | |
|
|
|
|
[第50楼]
[ 回复时间:2015-06-23 18:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-06-19 10:06 |
我的代码。为了简便,我只造了5组数据,书上的21组太多了。
借鉴了以上各楼的思想,没有用栈。win7 64bit + DosBox 测试通过。
---------------------------------------------
; 结构化寻址演练
; 将公司数据输入表格并计算年人均收入
assume cs:code
data segment
db '1975', '1976', '1977', '1978', '1979' ; 年份
dd 345980, 590827, 803530, 1183000, 1843000 ; 总收入
dw 5635, 8226, 11542, 14430, 15257 ; 人数
data ends
table segment
db 5 dup ('year summ ne ?? ')
table ends
code segment
start:
mov ax, data ; ds指向data段
mov ds, ax
mov ax, table ; es指向table段
mov es, ax
mov bx, 0 ; 初始化各数据索引
mov si, 0
mov di, 0
mov cx, 5 ; 设置循环次数
s:
; 源数据的3个结构体分别是
; 年份 ds:0[si] 共4字节
; 总收入 ds:20[si] 共4字节
; 员工数 ds:40[di] 共2字节
;
; table数据的结构体为 es:[bx]
; 4个成员分别是
; 年份 es:[bx].0 或 es:0[bx]
; 总收入 es:[bx].5 或 es:5[bx]
; 员工数 es:[bx].10 或 es:10[bx]
; 平均收入 es:[bx].13 或 es:13[bx]
mov ax, 0[si] ; 复制年份
mov es:[bx].0[0], ax
mov ax, 0[si+2]
mov es:[bx].0[2], ax
mov ax, 20[si] ; 复制总收入
mov es:[bx].5[0], ax
mov dx, 20[si+2]
mov es:[bx].5[2], dx
mov ax, 40[di] ; 复制员工数
mov es:[bx].10, ax
; 被除数总收入为32字节,AX中为低16位,DX为高16位
; 除数员工数为16字节,结果中商放在AX,余数放在DX
; 把复制总收入的代码写在复制员工数代码的后面,可以
; 少些一条ax的赋值语句
mov ax, 20[si] ; 计算人均收入
div word ptr 40[di]
;div word ptr es:[bx].10
mov es:[bx].13, ax
add si, 4
add di, 2
add bx, 16
loop s
mov ax, 4c00H
int 21H
code ends
end start | | |
|
|
|
|
[第51楼]
[ 回复时间:2015-10-16 15:10 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-08-31 21:48 |
回复:[第8楼]
------------------
s:mov ax,ds:0[si] ;copy year
mov es:0[bx],ax
mov ax,ds:0[si+2]
mov es:0[bx+2],ax
为什么是要每次加2 | | |
|
|
|
|
[第52楼]
[ 回复时间:2015-11-08 16:20 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-11-08 16:13 |
用16楼的代码在masm,link后输***.exe会正常运行程序并到下一行继续等待命令,然而我的不行,直接卡主了,而且debug中用g命令也是卡主,只能关了重来。
不知道是哪里的原因,求大神指点。
assume cs:code,ds:data
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 sumn ne ?? ')
table ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0 ;源数据位置
mov ax,table
mov es,ax
mov di,0 ;目标位置
mov cx,21
trans: ;year
mov ax,ds:[si] ;ax存低两位,dx存高两位
mov dx,ds:[si+2]
mov es:[di],ax
mov es:[di+2],dx
;sum
mov ax,ds:84[si]
mov dx,ds:86[si]
mov es:[di+5],ax
mov es:[di+7h],dx
;employee
mov bx,ds:168[si]
mov es:[di+10],bx
div bx
;average
mov word ptr es:[di+14],ax
add di,16
add si,4
loop trans
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第53楼]
[ 回复时间:2015-12-08 13:16 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2015-09-06 12:05 |
|
|
|
|
|
[第54楼]
[ 回复时间:2016-05-06 12:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2016-05-04 20:02 |
回复:[贴 主]
------------------
问题来了,怎么知道收入和人数有没有操作正确。年份还可以从ASCII码看出,但是收入和人数看不出来啊 | | |
|
|
|
|
[第55楼]
[ 回复时间:2018-08-01 17:06 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2018-07-30 20:26 |
= = 看来这帖子有些年头了...2018年了现在都 | | |
|