鱼C论坛

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

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

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

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

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

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


  下面是代码,我也就不隐藏了,没必要,不过我希望各位朋友都能把自己的思路分享一下,大家一起进步。
assume ds:data,cs:code,SS:stack,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,690827,803530,1183000,1843000,2759000,3753000,4649000,593700
        
  ;人数
  dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  dw 11542,14430,45257,17800
data ends

;栈
stack segment
  Db 160 dup(0)
stack ends

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

code segment
start:
  MOV AX,data
  MOV DS,AX

  MOV AX,table
  MOV ES,AX

  MOV AX,stack
  MOV SS,AX
  MOV sp,160

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

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

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

    ;写入人数
    MOV AX,DS:168[di]
    MOV DX,0
  
    PUSH SI
   
    add SI,18
    CALL xssr
     
    POP SI


    ;写入平均工资

    PUSH CX 
    
    MOV AX,84[bx]
    MOV DX,84[bx+2]
    MOV CX,DS:168[di]
    
    CALL chufa     ;计算平均工资  
    
    POP cx

    ; 这里又和上面一样了
    PUSH si
    add SI,30
    CALL xssr
    POP SI

    ADD DI,2
    ADD bx,4
    ADD SI,40
  LOOP S

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

  MOV DI,0
  MOV bx,0
  MOV CX,21
  s4:
    PUSH CX
    PUSH di

    MOV CX,40
    s5:
    MOV AL,[bx]
    MOV ES:[di],AL 
    MOV BYTE ptr ES:[DI+1],7

    ADD DI,2
    INC bx 
    LOOP s5
    
    POP DI
    POP cx
    ADD DI,160
    
  LOOP s4

  MOV AX,4c00h
  INT 21h


 



  ;因为年份本身就是以ascii码存放的,所以就不要转换,直接写到目标空间就行了
  chuansong:
    PUSH CX  
    PUSH SI
    PUSH bx
    PUSH ax
    
    MOV CX,4
    NF:
      MOV AL,[bx]
      MOV ES:[si],AL

      INC si
      INC bx 
    LOOP NF

    POP ax
    POP bx
    POP si
    POP CX
    RET 


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

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

    MOV CX,DX    ;将余数给cx  ,ax存商的低16位,dx存高16位
    POP DX
    
    POP bx 
    RET




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

    ADD CL,30h    ;将余数转换为ascii码, +30H,这里不明白为什么是加30H ,自己去对照ascii码表
    
    MOV CH,0      ;现在开始将每一次的余数压栈, 因为栈运算是操作2个字节,所以我用将ch置0,cl本身就是存放的余数。
    PUSH CX 
    
    INC DI        ;每一次入栈记录 次数
    
    MOV CX,DX     ;判断商是否为0 ,为零就不要在取余数了, dx存放高位商,前面解释过了
    JCXZ pdax     ;如果高位商为零, 说明 整个商 可能为零, 不过高位商不为零,那低位商也就不需要判断了,,说实话真麻烦
    
  JMP H  
  
  pdax:
    MOV CX,AX    ;判断 低位商是否为0
    JCXZ OK      ;如果这里被执行,说明 整个商为零,然后就开始pop了,真正的写入数据到目标空间
    JMP H
  OK:
    MOV CX,DI    ;di 为余数的个数,也就代表push了几次,所以我们就要循环pop几次
    zha:
      
      POP AX     ;将余数出栈
      MOV ES:[si],AL  ;前面入栈的时候  cl 为余数,ch为0, 所有al 对应 cl 
      INC SI     
    LOOP zha 
    POP DI 
    POP si
    POP CX 
    ret
code ends
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-12-27 15:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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