. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->数据处理的两个基本问题
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  绝了!比置顶程序还要牛的程序,不另外定义段,只用23条汇编指令完成程序要求。比最牛程序少用了七行代码。  [待解决] 回复[ 66次 ]   点击[ 6561次 ]  
netson
[帖 主]   [ 发表时间: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  希望与热爱技术的人为伍。
wsrf
[第1楼]   [ 回复时间:2009-07-02 14:04 ]   [引用]   [回复]   [ top ] 
荣誉值:33
信誉值:0
注册日期:2008-10-16 10:01
支持一下。
wsay666
[第2楼]   [ 回复时间:2009-07-13 14:22 ]   [引用]   [回复]   [ top ] 
荣誉值:1
信誉值:8
注册日期:2009-06-27 18:30
讨厌,刚才在一博客上看到这段代码,着实佩服了一番.原来,他是抄你的.真是的.不劳而获.
asongsky
[第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
这段谁给看看
alabo886
[第4楼]   [ 回复时间:2009-10-16 19:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-09 19:25
I服了YOU!
alabo886
[第5楼]   [ 回复时间:2009-10-16 19:22 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-10-09 19:25
3楼的程序简直是莫名其妙啊
john_asmedu
[第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
john_asmedu
[第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
luoguolong2660
[第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
学了两天编出来的程序,大家看下
regex
[第9楼]   [ 回复时间:2010-01-14 22:59 ]   [引用]   [回复]   [ top ] 
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51
顶楼上的, 学两天就可以写出这么漂亮的代码。。。羡慕。
famingyuan
[第10楼]   [ 回复时间:2010-03-19 15:48 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-11-16 13:00
只能说,你很牛
zjkl19
[第11楼]   [ 回复时间:2010-03-27 18:34 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2009-07-15 11:17
8楼好强啊,我自己虽然也写出这个程序了,但是效率不如你的。
outgrow
[第12楼]   [ 回复时间:2010-05-18 13:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-05-18 12:52
都是牛人,我的就有多个循环
wulishuijiao
[第13楼]   [ 回复时间:2010-06-04 17:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-05-28 23:02
8楼的2天就那么牛了,我无地自容了,在给你几天中国就该出自己的系统了,有希望
chever19
[第14楼]   [ 回复时间:2010-07-17 19:30 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-07-12 14:54
嘿嘿~我写的和8楼的兄弟的几乎一样~但我已经学了7,8天了~!!
imandry
[第15楼]   [ 回复时间:2010-07-17 22:34 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2010-07-13 10:33
汗~八楼的“两”是确数还是约数……【别怪我,老师说……要严谨……
lelmon
[第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里最好的之一了。。。
liuquanhao7232
[第17楼]   [ 回复时间:2010-07-30 18:33 ]   [引用]   [回复]   [ top ] 
荣誉值:8
信誉值:0
注册日期:2010-07-12 08:47
楼上的,你的dx应该先初始化一下吧。直接用虽然可以但好像不妥。
int20
[第18楼]   [ 回复时间:2010-08-06 06:33 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:0
注册日期:2010-07-25 14:15
都这么厉害...
hearthit
[第19楼]   [ 回复时间:2010-09-12 19:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-09-03 12:12
实在是高。。。。。
18757223
[第20楼]   [ 回复时间:2010-10-09 17:48 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-09 17:39
goingstudy
[第21楼]   [ 回复时间:2010-10-14 22:44 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-12 21:57
都很厉害啊 ,学习啊
michael47
[第22楼]   [ 回复时间:2010-10-30 21:14 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-13 21:26
跟十六楼的一样,感觉这样是最合适的。
godok220
[第23楼]   [ 回复时间:2010-11-05 22:08 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-21 13:38
今天看的头痛,这个帖子导致我吐了,不是恶心各位,别误会。
xiaojian2010
[第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
欢迎讨论交流
xiaojian2010
[第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楼的同学忘了内存单元高位地位的存放顺序了,惭愧。。
chenchaosx
[第26楼]   [ 回复时间:2010-12-04 21:00 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-12-04 20:54
哎!大意了,闭门造车N个月,原来这里有这么多高手,多好的资源啊,这个程序我也写出来了,用了N个loop,还沾沾自喜,惭愧啊!!! 多谢楼主,也多谢各楼兄弟!往后多指教!
chenchaosx
[第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
one_cai
[第28楼]   [ 回复时间:2010-12-14 11:39 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-12-05 15:22
7楼才牛逼。。。看了7楼可以真正体会到数组和结构体的精髓。
其他的勉强吧
one_cai
[第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
one_cai
[第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
three-stone
[第31楼]   [ 回复时间:2010-12-23 14:24 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-21 15:56
其实 我在怀疑你们到底有没有调试过。
程序运行完全不对头。
static
[第32楼]   [ 回复时间:2010-12-26 17:40 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-10-06 11:12
没错,来个调试过的程序
character_w
[第33楼]   [ 回复时间:2011-02-12 20:55 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2011-01-29 19:28
回复:[第29楼]
------------------
请恕我眼拙,实在没看出这有什么精妙之处,没有任何瞧不起的意思,只是想要问问,这样写有什么
好处,个人感觉只是不同的寻址方式,有什么区别吗?
谢谢,才学编程没几天,C语言也只是刚看到数组,指针那块。
谢谢
leizhengpeng
[第34楼]   [ 回复时间:2011-02-20 01:53 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-02-02 04:30
其实 我在怀疑你们到底有没有调试过。
程序运行完全不对头。
------------------
回复:是啊???
youguiqing
[第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
youguiqing
[第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.
wlzaini1314
[第37楼]   [ 回复时间:2011-03-12 20:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-01-15 22:31
请问  哥哥你调试了么?
a88510
[第38楼]   [ 回复时间:2011-03-16 04:38 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-01-26 21:21
。。。。。八楼基础好,之前肯定学过C语言或者其他的,不可能白手起家两天弄出个来
9kk
[第39楼]   [ 回复时间:2011-03-22 01:41 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-03-19 14:07
7楼最后顺序都点不对啊,8楼的赞一个,精干
wgs361
[第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.
kgate
[第41楼]   [ 回复时间:2011-04-07 13:38 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-04-04 12:01
不知道为什么我调试他们的程序,除了40楼的正常,年份输出都有问题。都显示不全,不知各位有没有出现这种状况?
wlzaini1314
[第42楼]   [ 回复时间:2011-04-16 19:05 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-01-15 22:31
一楼  我跟踪了你的程序 复制的只是  19 没别的了
wlzaini1314
[第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
xohome
[第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
zjkl19
[第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个字节存储公司每年的排名,这种方法就不行了。从结构化的角度来说,不如多用几个循环,使程序变得清晰。
jumpbird
[第46楼]   [ 回复时间:2014-09-02 22:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2014-08-29 19:48
那是因为mov dx,{bx+2} 这行写成大括号了。
gaming
[第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
jas05
[第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
zzqcn
[第49楼]   [ 回复时间:2015-06-21 11:12 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2015-06-19 10:06
To 7楼 和 30楼:

你们的代码是有问题的:在算平均收入那个地方,你们的代码中,AX中的值已经不是总收入的低16位了,而这里被除数是32位,要求低16位在AX中,高16位在DX中。
zzqcn
[第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
11080903
[第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
uiiunan
[第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
lshhjx
[第53楼]   [ 回复时间:2015-12-08 13:16 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2015-09-06 12:05
楼主确认不是抄写别人的?
ysuzmj2016
[第54楼]   [ 回复时间:2016-05-06 12:18 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2016-05-04 20:02
回复:[贴 主]
------------------
问题来了,怎么知道收入和人数有没有操作正确。年份还可以从ASCII码看出,但是收入和人数看不出来啊
menghs_begin
[第55楼]   [ 回复时间:2018-08-01 17:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2018-07-30 20:26
= = 看来这帖子有些年头了...2018年了现在都
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved