鱼C论坛

 找回密码
 立即注册
查看: 4655|回复: 14

[汇编作业] 【王爽汇编】课程设计1,源码及详细分析。

[复制链接]
发表于 2014-5-22 22:10:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
(46P[G}])~$Y]]QEWKO78FT.jpg
   本来也没认为自己能写出来的,好多次想放弃的,可能心里有点不甘心吧,昨天晚上开始写,今天白天花了一天时间在公司研究,主要是前面卡在那个 取余数地方,现在写了出来,也是想分享一下我的心情,我觉得呢,这代码啊,还是别一次性想完,因为你也想不完,刚开始的时候,我也一点头绪都没有,然后我想,那就先把年份输出来吧,这个我肯定会做啊,然后当我写了一点的时候我发现,那个收入我应该也能输出来啊,然后就一点一点的写玩了,虽然会出现很多错误,但是我挺享受这种过程的,感觉反正就是一个值爽。
   下面我就来讲一下我分析这个程序的思路吧:
    1.我先开辟一段空间,来保存 所有转换后的 年份,收入,人数,平均工资
    2.将所有的数据写入到显存
    3.年份这个很好办,本身就是ascii码数据,直接写入就行了
    4.收入,这个需要写一个取余数的方法就行了,主要是要知道怎样让数据的顺序不变,因为取余数是从低到高(这里代码里面有相信分析)
    5.人数  和和上面一样。平均工资,也就多了一个 除法的方法。


  下面是代码,我也就不隐藏了,没必要,不过我希望各位朋友都能把自己的思路分享一下,大家一起进步。

  1. assume ds:data,cs:code,SS:stack,ES:table
  2.        
  3. data segment
  4.   ;年份
  5.   db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  6.   db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  7.   db '1993','1994','1995'
  8.         
  9.   ;收入
  10.   dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  11.   dd 345980,690827,803530,1183000,1843000,2759000,3753000,4649000,593700
  12.         
  13.   ;人数
  14.   dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  15.   dw 11542,14430,45257,17800
  16. data ends

  17. ;栈
  18. stack segment
  19.   Db 160 dup(0)
  20. stack ends

  21. ;保存年份 收入 人数 平均工资 ,里面的空格我写了40个,这里面都是保存转换成ascii码后的数据
  22. table segment
  23.   DB 21 dup('                                         ')
  24. table ends

  25. code segment
  26. start:
  27.   MOV AX,data
  28.   MOV DS,AX

  29.   MOV AX,table
  30.   MOV ES,AX

  31.   MOV AX,stack
  32.   MOV SS,AX
  33.   MOV sp,160

  34.   MOV CX,21
  35.   MOV bx,0     ;索引年份和收入,每一个数据都是4个字节
  36.   MOV SI,0     ;索引目标空间
  37.   MOV DI,0     ;索引人数,每一个数据都是2个字节
  38.   S:
  39.     CALL chuansong   ;写入年份

  40.     ;写入收入
  41.     MOV AX,84[bx]     ;收入的低16位
  42.     MOV DX,84[bx+2]   ;收入的高16位
  43.    
  44.     PUSH si
  45.     add SI,8          ;从偏移地址为8的空间开始写入
  46.     CALL xssr
  47.     POP SI

  48.     ;下面的写入人数,和计算平均工资,简单看看就能看懂,都是调用一个方法

  49.     ;写入人数
  50.     MOV AX,DS:168[di]
  51.     MOV DX,0
  52.   
  53.     PUSH SI
  54.    
  55.     add SI,18
  56.     CALL xssr
  57.      
  58.     POP SI


  59.     ;写入平均工资

  60.     PUSH CX
  61.    
  62.     MOV AX,84[bx]
  63.     MOV DX,84[bx+2]
  64.     MOV CX,DS:168[di]
  65.    
  66.     CALL chufa     ;计算平均工资  
  67.    
  68.     POP cx

  69.     ; 这里又和上面一样了
  70.     PUSH si
  71.     add SI,30
  72.     CALL xssr
  73.     POP SI

  74.     ADD DI,2
  75.     ADD bx,4
  76.     ADD SI,40
  77.   LOOP S

  78.   ; 这下面就是 输出了很简单,我就不解释了,好累。
  79.   MOV AX,0b800h
  80.   MOV ES,AX
  81.   MOV AX,table
  82.   MOV DS,AX

  83.   MOV DI,0
  84.   MOV bx,0
  85.   MOV CX,21
  86.   s4:
  87.     PUSH CX
  88.     PUSH di

  89.     MOV CX,40
  90.     s5:
  91.     MOV AL,[bx]
  92.     MOV ES:[di],AL
  93.     MOV BYTE ptr ES:[DI+1],7

  94.     ADD DI,2
  95.     INC bx
  96.     LOOP s5
  97.    
  98.     POP DI
  99.     POP cx
  100.     ADD DI,160
  101.    
  102.   LOOP s4

  103.   MOV AX,4c00h
  104.   INT 21h






  105.   ;因为年份本身就是以ascii码存放的,所以就不要转换,直接写到目标空间就行了
  106.   chuansong:
  107.     PUSH CX  
  108.     PUSH SI
  109.     PUSH bx
  110.     PUSH ax
  111.    
  112.     MOV CX,4
  113.     NF:
  114.       MOV AL,[bx]
  115.       MOV ES:[si],AL

  116.       INC si
  117.       INC bx
  118.     LOOP NF

  119.     POP ax
  120.     POP bx
  121.     POP si
  122.     POP CX
  123.     RET


  124.   ;16位除法
  125.   ;参数,(被除数)高位dx,低位cx,除数cx
  126.   ;返回值,高位dx,低位cx,余数cx
  127.   chufa:
  128.     PUSH bx
  129.    
  130.     MOV bx,AX    ;先保存低16位
  131.     MOV AX,DX    ;先计算高16位,将高16位给ax
  132.    
  133.     MOV DX,0     ;为了不影响 16 位除法运算 所以我清空dx ,这里不明白的可以百度 一下 div 16运算
  134.     DIV CX
  135.     PUSH AX      ;保存高位

  136.     MOV AX,bx    ;bx 先前保存的是低16位 ,现在还原继续球低16位运算
  137.     DIV CX

  138.     MOV CX,DX    ;将余数给cx  ,ax存商的低16位,dx存高16位
  139.     POP DX
  140.    
  141.     POP bx
  142.     RET




  143.   ;
  144.   xssr:
  145.     PUSH CX
  146.     PUSH SI
  147.     PUSH DI
  148.    
  149.      ;di是用来记录 当前 数据的 位数  假如数据是1234  那di就是=4,
  150.      ;这个di我用来将数据倒置,因为取余数,后的数据就变成 4321 了,数据就不对,
  151.      ;所以我每次取一个余数就push 一次,然后记录次数,最后就pop出去,这样就能使数据不会倒过来
  152.    
  153.     MOV DI,0  
  154.   H:
  155.    
  156.     MOV CX,10     ; 10进制除以10 取余数
  157.    
  158.     CALL chufa    ;取出余数,余数是放在cx里面,其实是在cl里面

  159.     ADD CL,30h    ;将余数转换为ascii码, +30H,这里不明白为什么是加30H ,自己去对照ascii码表
  160.    
  161.     MOV CH,0      ;现在开始将每一次的余数压栈, 因为栈运算是操作2个字节,所以我用将ch置0,cl本身就是存放的余数。
  162.     PUSH CX
  163.    
  164.     INC DI        ;每一次入栈记录 次数
  165.    
  166.     MOV CX,DX     ;判断商是否为0 ,为零就不要在取余数了, dx存放高位商,前面解释过了
  167.     JCXZ pdax     ;如果高位商为零, 说明 整个商 可能为零, 不过高位商不为零,那低位商也就不需要判断了,,说实话真麻烦
  168.    
  169.   JMP H  
  170.   
  171.   pdax:
  172.     MOV CX,AX    ;判断 低位商是否为0
  173.     JCXZ OK      ;如果这里被执行,说明 整个商为零,然后就开始pop了,真正的写入数据到目标空间
  174.     JMP H
  175.   OK:
  176.     MOV CX,DI    ;di 为余数的个数,也就代表push了几次,所以我们就要循环pop几次
  177.     zha:
  178.       
  179.       POP AX     ;将余数出栈
  180.       MOV ES:[si],AL  ;前面入栈的时候  cl 为余数,ch为0, 所有al 对应 cl
  181.       INC SI     
  182.     LOOP zha
  183.     POP DI
  184.     POP si
  185.     POP CX
  186.     ret
  187. code ends
  188. end start
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-5-22 22:18:55 | 显示全部楼层
我也要自己写一个:mad::mad::mad::mad:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-23 08:02:19 | 显示全部楼层
我自己也去写一个看看呀。哈哈。:lol:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-23 08:08:44 From FishC Mobile | 显示全部楼层
我以前用了一个星期写…………
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-24 20:17:37 | 显示全部楼层
我也是刚写出来,共同进步
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-24 20:18:12 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-24 20:31:29 From FishC Mobile | 显示全部楼层
decoder 发表于 2014-5-24 20:18
第一次写,用了五天

我五天在学校写代码 1天在家调试 第七天成功了!  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-24 20:33:53 | 显示全部楼层
15岁的小朋友 发表于 2014-5-24 20:31
我五天在学校写代码 1天在家调试 第七天成功了!

:handshake牛,我刚刚写完,大脑已经不听使唤了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-24 22:55:33 From FishC Mobile | 显示全部楼层
decoder 发表于 2014-5-24 20:33
牛,我刚刚写完,大脑已经不听使唤了

累了 就早点睡罗  我刚写完也是这样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-4 23:14:31 | 显示全部楼层
本帖最后由 kikiatw 于 2014-6-4 23:38 编辑

寫好久的...

ASSUME CS:CODE, DS:DATA, SS:STACK

DATA SEGMENT
DB        '1975','1976','1977','1978','1979','1980','1981'        ;0
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                        ;84
DD        50065,97479,140417,197514,345980,590827,803530
DD        1183000,1843000,2759000,3753000,4649000,5937000

DW        3,7,9,13,28,38,130                                        ;168
DW        220,476,778,1001,1442,2258,2793
DW        4037,5635,8226,11542,14430,15257,17800
DATA ENDS

TABLE SEGMENT
DB        21 DUP ('YYYY EARN EP AV ')
TABLE ENDS

STACK SEGMENT
DW        50H DUP (0)
STACK ENDS

CODE SEGMENT
MAIN:
        MOV AX,STACK                ;initial stack segment
        MOV SS,AX
        MOV SP,50H

        MOV AX,DATA                ;initial data into table segment
        MOV DS,AX
        MOV AX,TABLE
        MOV ES,AX
        CALL SORT

        MOV AX,TABLE                ;initial print data
        MOV DS,AX
        MOV AX,0B800H
        MOV ES,AX
        MOV BX,0
        MOV SI,0
        MOV DI,0
        MOV CX,21

M1:        PUSH CX
        MOV AX,[SI]                ;print character
        MOV ES:[DI],AL
        MOV ES:[DI+2],AH       
        MOV AX,[SI+2]
        MOV ES:[DI+4],AL
        MOV ES:[DI+6],AH

        MOV AX,[SI+7]                ;print DEC number to string
        MOV DX,[SI+5]
        MOV CX,DI
        ADD CX,20H
        CALL DTOC32

        MOV AX,0                ;print DEC number to string
        MOV DX,[SI+10]
        MOV CX,DI
        ADD CX,40H
        CALL DTOC32

        MOV AX,0                ;print DEC number to string
        MOV DX,[SI+13]
        MOV CX,DI
        ADD CX,60H
        CALL DTOC32

        ADD SI,10H
        ADD DI,0A0H
        POP CX
        LOOP M1

        MOV AX, 4C00H
        INT 21H

SORT:        MOV CX,21
        MOV BX,0
        MOV SI,0
        MOV DI,0
S1:        PUSH CX
        MOV AX,[SI]
        MOV ES:[DI],AX
        MOV AX,[SI+2]
        MOV ES:[DI+2],AX
        MOV AX,84[SI]
        MOV ES:[DI+5],AX
        MOV DX,86[SI]
        MOV ES:[DI+7],DX
        MOV CX,168[BX]
        MOV ES:[DI+10],CX
        DIV CX
        MOV ES:[DI+13],AX
        ADD DI,10H
        ADD SI,04H
        ADD BX,02H
        POP CX
        LOOP S1
        RET

;DTOC32 show the double word DEC on the screen
;AX:H word
;DX:L word
;CX:Location offset at B800H Segment
DTOC32:        PUSH DI
        PUSH SI
        MOV DI,CX        ;DI location pointer
        MOV SI,DX        ;SI to save low word
        MOV BX,0        ;BX to be byte count
DT1:        MOV DX,0
        MOV CX,10
        DIV CX
        MOV CX,AX
        MOV AX,SI
        MOV SI,CX
        MOV CX,10
        DIV CX
        PUSH DX
        INC BX
        MOV CX,AX
        JCXZ DT2
        MOV AX,SI
        MOV SI,CX
        JMP DT1
DT2:        MOV CX,BX
DT3:        POP DX
        ADD DL,30H
        MOV ES:[DI],DL
        ADD DI,2
        LOOP DT3

        POP SI
        POP DI
        RET

CODE ENDS
END MAIN

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-4 23:32:54 | 显示全部楼层
樓主請問一下您代碼是怎麼貼的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-5 00:37:45 | 显示全部楼层
学习下!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-6 20:46:16 | 显示全部楼层
{:1_1:}:sad:big:cry:shy::ton::shock:学习下!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-11-26 14:47:40 | 显示全部楼层
kikiatw 发表于 2014-6-4 23:32
樓主請問一下您代碼是怎麼貼的?

在发表工具档时有<>,点这个,再贴上去。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-11-29 20:08:17 | 显示全部楼层
我用了两种方法,一种和楼主一样,先开一段空间存转成字符以0为间隔,然后再存入显存;另一种是字符转化和存入显存同时进行,不用空间先储存转化好的字符,一步到位。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-26 23:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表