鱼C论坛

 找回密码
 立即注册
查看: 2569|回复: 4

[汇编作业] 第十章课程设计1____源码————————

[复制链接]
发表于 2014-5-24 19:20:54 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 decoder 于 2014-5-24 19:55 编辑
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,97478,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
        dw 3,7,9,13,28,38,130,220,476,778,1001,1422,2258,2793,4037,5635,8226
        dw 11542,14430,15257,17800
data ends

buff_mem segment   
   db 1280 dup(0)   ;48个字节储存一行数据,共使用1008个字节为了内存对齐申请1280字节内存空间  
buff_mem ends
;es:[3f0]  21年循环变量 3f0h  3f0h
;es:[3202]  年数据最低位 3f2h  3f2h
;es:[3203]  年数据次低位 3f3h  3f3h
;es:[3204]  年数据次高位 3f4h  3f4h
;es:[3205]  年数据最高位 3f5h  3f5h
;es:[3206]  除数         3f6h 3f6h
;es:[3208]  四位十六进制数除法的低位商       3f8h 3f8h
;es:[3210]  四位十六进制除法的   余数 3fah 3fah
;es:[3212]   ds:[bx]中bx的值         3fch 3fch
;es:[3214]  保存bp的值    3f8h  3feh
;es:[3216]  保存di的值          0400h
;ds:[0402]  保存字符处理循环中的临时cx变量
;ds:[0404]  保存显示函数中的di
code segment
     start:              call get_data
                           call process_data   ;0014
                           call display_data
                           mov ax,4c00h
                           int 21h
        
    get_data:       mov ax,data
                          mov ds,ax
        ret
     process_data:                                    ;ip=0014
                           ;初始化
                         mov ax,buff_mem ;es指向buff_mem  es=0b5e
                         mov es,ax
                         mov bx,0
                         mov si,84           ;数据偏移到收入地址
                         mov bp,0
                         mov di,48            ;行递增数据,初始化为距左边4字节
                         mov cx,21
                                                 
     _loop_21_:   push cx        ;保存21年的循环
                          mov es:[0400h],di        ;保存21年循环中di的当前值
                          mov es:[3feh],bp
                          call covent_year        ;年份       ip=0086
                          call covent_summ        ;资产       ip=00a3
                          call covent_ne          ;人数       ip=00e0
                          call covent_pcdi        ;人均收入
                          pop cx 
                          dec cx 
                          jcxz _l_21_out
                          add bp,4 
                          add di,2ch
                          add word ptr es:[3fch],4        ;bx镜像递增
                          mov bx,es:[3fch]
                           jmp _loop_21_
        _l_21_out:  ret        
                                                 
        display_data:       
                          mov ax,0b80ah
                          mov es,ax 
                          mov ax,buff_mem
                          mov ds,ax
                          mov bx,0
                          mov si,0
                          mov bp,0
                          mov di,20h
                          mov cx,21 
                                                
                       b:push cx 
                          push di            ;用来定位要显示字符的位置
                          push bx            ;用来定位要载入字符的位置
                          mov ds:[404h],di   ;定位年列的位置
                          mov cx,4
          get_year: push cx            ;年份字符串的循环处理
                          mov cx,ds:[bx]    ;取得年份字符的
                          mov es:[di],cx 
                          pop cx 
                          add bx,2
                          add di,2
                          loop get_year
                          add di,16
                          mov cx,8
                          mov ax,0
                          add word ptr ds:[404h],16   ;定位资产列的位置
                          mov di,ds:[404h]
 _get_summ:     push cx            ;资产字符串的循环处理
                          mov cx,ds:[bx]
                          jcxz _summ_eq0     ;判断字符是否为空,在48字节的段中去掉空格存入显存
                          mov es:[di],cx 
                          add di,2
 _summ_eq0:    add ax,2
                         add bx,2 
                         pop cx 
                         loop _get_summ
                         add di,16
                         mov cx,8 
                         sub di,ax
                         add di,16
                         add word ptr ds:[404h],20  ;定位人员列的位置
                         mov di,ds:[404h]
 get_ne:            push cx 
                         mov cx,ds:[bx]             ;取得人员的字符
                         jcxz _cx_ne_eq_0  ;判断字符是否为空,在48字节的段中去掉空格存入显存
                         mov es:[di],cx 
                         add di,2 
 _cx_ne_eq_0: add ax,2
                         add bx,2 
                         pop cx 
                         loop get_ne
                         add di,16
                         mov cx,4 
                         sub di,ax
                         add di,32
                         add word ptr ds:[404h],16  ;定位人均收入列的位置
                         mov di,ds:[404h]
  get_sr:            push cx 
                         mov cx,ds:[bx]             ;取得人均收入位置的字符
                         jcxz _cx_sr_eq_0    ;判断字符是否为空,在48字节的段中去掉空格存入显存
                         mov es:[di],cx 
                         add di,2 
 _cx_sr_eq_0:  add ax,2
                         add bx,2 
                         pop cx 
                         loop get_sr
                         add di,16
                         pop bx
                         pop di
                         add di,0a0h
                         add bx,48
                         pop cx 
                         dec cx 
                         jcxz dp_out
                         jmp b            ;此处原本用loop循环,但循环溢出,只能使用jmp段内转移
dp_out:             ret


covent_year:    push bx                      ;ip=0086   年份字符串处理
                         push si 
                         push bp 
                         push di
                         mov cx,4
                                                 
_loop_str:        mov al,byte ptr ds:[bx];年的单位字节数据
                        mov byte ptr es:[bp+di-48],al 
                        mov byte ptr es:[bp+di-47],07h 
                        inc bx 
                        add bp,2
                        loop    _loop_str
                       pop di 
                       pop bp 
                       pop si 
                       pop bx 
    ret
        
covent_summ: push bx                     ;ip=00a3  资产字符串处理
                       push si 
                       push bp 
                       push di
                       mov ax,word ptr ds:[bx+si]
                       mov dx,word ptr ds:[bx+si+2]
                       mov word ptr es:[3f6h],10
_div_loop:       call divdw                    ;cx为余数,ax为商
                       mov word ptr es:[3fah],cx   ;余数用来做显示位
                       add word ptr es:[3fah],30h  ;转换成字符
                       mov ax,word ptr es:[3fah]   ;字符放入ax
                       mov ah,07h                   ;把ah变成颜色位
                       mov word ptr es:[bp+di-26],ax   ;保存入显示缓冲中
                       mov ax,word ptr es:[3f8h]    ;低位商
                       mov cx,ax 
                       jcxz _div_out                ;只要低位商为零就跳出
                       sub bp,2                     ;从后往前放资产值
                       jmp _div_loop
_div_out:        pop di 
                       pop bp 
                       pop si 
                       pop bx 
            ret
        
covent_ne:    push bx                     ;ip=00e0   人员字符串处理
                      push si 
                      push bp 
                      push di
                      push word ptr es:[3fch]
                                                 
                      mov cx,es:[3fch]             ;被保存的bx的值??????
                      mov ax,cx                     
                      jcxz _init_data               ;检测第一次循环bx是否为零,若为零则跳过-2步骤
                      mov dx,0
                      mov cx,2
                      div cx                        ;4/2,8/2,12/2,16/2....
                      mov bx,ax                     ;2,4,6,8....
                                                 
 _init_data:     mov ax,ds:[bx+si+84]        ;ax的值是ne部分
                      mov dx,0                     ;因为都是求余数,并且人数不会超过32位
_divw_loop:   call divdw
                      mov word ptr es:[3fah],cx   ;余数用来做显示位
                      add word ptr es:[3fah],30h  ;转换成字符
                      mov ax,word ptr es:[3fah]   ;放入ax
                      mov ah,07h                   ;把ah变成颜色位
                      mov word ptr es:[bp+di-14],ax   ;保存入显示缓冲中32-8-20
                      mov ax,word ptr es:[3f8h]   ;低位商
                      mov dx,0
                      mov cx,ax 
                      jcxz _divw_out                ;只要低位商为零就跳出
                                                 
                      sub bp,2                      ;从右到左(从小到大)写数据
                      jmp _divw_loop
_divw_out:    pop word ptr es:[3fch]
                      pop di 
                      pop bp 
                      pop si 
                      pop bx 
                                                
        ret        
        
covent_pcdi:                                      ;ip=013b  人均收入字符串处理
                     push bx                     ;ip=00e0   人员字符串处理
                     push si 
                     push bp 
                     push di
                     push word ptr es:[3fch]
                     mov ax,word ptr ds:[bx+si]      ;把资产低位当作被除数
                     mov dx,word ptr ds:[bx+si+2]    ;把资产高位当作被除数
                     push ax                           ;此处注意保存ax和dx的值
                     push dx 
                                                
                     mov cx,es:[3fch]             ;被保存的bx的值??????
                     mov ax,cx                      
                     jcxz _init_ne_data               ;检测第一次循环bx是否为零,若为零则跳过-2步骤
                     mov dx,0
                     mov cx,2
                     div cx                        ;4/2,8/2,12/2,16/2....
                     mov bx,ax                     ;2,4,6,8....
                                                
_init_ne_data: pop dx                          ;还原dx和ax的值
                     pop ax 
                     mov cx,ds:[bx+si+84]
                     mov word ptr es:[3f6h],cx   ;把人数当作除数
                     call divdw
                     mov word ptr es:[3fah],ax   ;商用来做人均收入的被除数
                     mov word ptr es:[3f6h],10   ;循环中的除数,意思是缩小十倍
                     mov dx,0 
        pcdi_:    call divdw
                     mov word ptr es:[3fah],cx   ;余数用来做显示位
                     add word ptr es:[3fah],30h  ;转换成字符
                     mov ax,word ptr es:[3fah]   ;字符放入ax
                     mov ah,07h                   ;把ah变成颜色位
                     mov word ptr es:[bp+di-2],ax  ;保存入显示缓冲中
                     mov ax,word ptr es:[3f8h]    ;低位商
                     mov cx,ax 
                     jcxz pcdi_out                ;只要低位商为零就跳出
                     sub bp,2                     ;从后往前放资产值
                     jmp pcdi_
                                                
pcdi_out:      pop word ptr es:[3fch]
                     pop di 
                     pop bp 
                     pop si 
                     pop bx
        ret        
        
        divdw:                    
                    push ax     ip= 0175h
                    mov ax,dx
                   mov dx,0
                    div word ptr es:[3f6h]    ;ax=ax/【x】 高位商  dx=ax/cx高位余  如果高位为零,则全为零
                    mov bx,ax ;bx=ax 如果高位被除为零则取ES:[510]的值为商
                    pop ax     ;ax=低位被除数 dx=在进行高位除法时作为高位被除数,低位时为余数(隐含高位被除数)
                   div word ptr es:[3f6h]     ;dx:ax= 14240  / cx= 0f
                   mov es:[3f8h],ax ;保存低位除法的商
                   mov cx,dx  ;将余数保存在cx
                   mov dx,bx  ;将商保存在dx(高位商)
        ret        
code ends 
end start
运行结果.jpg

评分

参与人数 1鱼币 +3 收起 理由
传说。 + 3 感谢楼主无私奉献!

查看全部评分

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

使用道具 举报

发表于 2014-5-25 01:31:34 | 显示全部楼层
碉堡了。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-25 01:34:00 | 显示全部楼层
楼主可有divdw 的解释?那里我不理解。 高16位 低16位怎么算出原数的商和余数。有推导么?
而且还是16进制的。搞不懂。跪求啊!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-25 09:41:07 From FishC Mobile | 显示全部楼层
传说。 发表于 2014-5-25 01:34
楼主可有divdw 的解释?那里我不理解。 高16位 低16位怎么算出原数的商和余数。有推导么?
而且还是16进制 ...

书里后面有公式证明 在附注5
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-30 04:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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