鱼C论坛

 找回密码
 立即注册
查看: 2759|回复: 8

[争议讨论] 最近刚写完汇编实验十课设一的有木有?

[复制链接]
发表于 2012-2-24 14:33:13 | 显示全部楼层 |阅读模式

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

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

x
如题。有的话 一起探讨一下的有吗?
子程序都编好了,但是最后封装在一起的时候一直出现各种问题。
但是却说不上来是什么问题。
有写好的各位大大一起探讨下的有吗?
麻烦加我qq:448440520
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 14:43:11 | 显示全部楼层
assume cs:code
data segment   
   db 10 dup(0)   
data ends   

stack segment  
   db 32 dup(0)  
stack ends  

table segment
  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514  
  dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000  
table ends
code segment
start:
                mov ax,data
                mov ds,ax
                mov ax,stack
                mov ss,ax
                mov sp,32
               
                mov cx,21                ;循环次数
                mov di,0                ;数据起始地址
                mov bl,0                ;设bl为显示缓冲区的行数变量
dd_data:
        push cx
                mov ax,table
                mov es,ax
                mov ax,es:[di]                ;将数据低16位数据给ax
                mov dx,es:[di+2]        ;将数据高16位数据给dx
                call dtoc
                mov dh,6                ;(dh)行数
                add dh,bl
                mov dl,3                ;(dl)列数
                mov cl,2                ;(cl)属性
                call show_str
                add di,4
                inc bl
        pop cx       
                loop dd_data
               
                mov ax,4c00h
                int 21h

;数值显示
;功能:数值转换,将10进制数值转换成ASCII码
;参数:(ax)=dword型数据低16位数据,(dx)=dword型数据高16位数据,ds:si=该数据起始地址
;返回:无
dtoc:
        push ax
        push cx
        push si
        push di
                mov si,0                ;记录数字个数
s1:       
                mov cx,10                ;除数等于10
                call divdw
                add cx,30h                ;将余数加上30H转换成ASCII码
                push cx                        ;将ASCII码推入栈中暂存
                inc si                        ;结果个数自增1
                mov cx,ax
                jcxz ok
                jmp s1
ok:       
                mov cx,si
                mov di,0
s2:       
                pop ax
                mov [di],al
                inc di
                loop s2
        pop di
        pop si
        pop cx
        pop ax
ret
;解决除法溢出的问题
;功能:进行不会产生溢出的除法程序,被除数为dword型,除数为word,结果为dword型
;参数:(ax)=dword型数据低16位数据,(dx)=dword型数据高16位数据,(cx)=除数
;返回:(dx)=结果的高16位,(ax)=结果的低16位,(cx)=余数
divdw:
        push bx
                push ax                        ;将低16位数据暂存栈中
                mov ax,dx                ;将高16位数据给ax
                mov dx,0                ;将余数清零避免干扰下面运算
                div cx                        ;计算int(H/N)
                mov bx,ax                ;将int(H/N)暂存bx中
                pop ax                        ;将低16位数据出栈给AX
                div cx                        ;计算(L+rem(H/N)*65536)/N
                mov cx,dx                ;将余数给cx
                mov dx,bx                ;将结果高16位给dx
        pop bx
ret

;显示字符串
;在指定的位置显示指定的颜色的字符串
;参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si指向首字符串
;返回:无
show_str:
        push ax
        push bx
        push cx
        push dx
        push si
                mov ax,0b800h
                mov es,ax
               
                mov al,160                        ;以下计算显示缓冲区的偏移地址
                dec dh
                mul dh
                mov bx,ax
               
                mov al,2
                mul dl
                sub dl,2
               
                add bx,ax                        ;将显示缓冲区的偏移地址给bx
                mov si,0                        ;初始化DS:SI指向字符串首地址
               
                mov ah,cl                        ;将属性给ah
s:
                mov ch,0                        ;将ch清0避免干扰下面判断
                mov cl,[si]                        ;
                jcxz return
                mov al,[si]                        ;将字符串ASCII码给al
                mov es:[bx],ax                ;将字符串ASCII码和属性给显示缓冲区
                inc si                                ;指向下一个字符
                add bx,2                        ;指向下一个显示缓冲区
                jmp s
return:
        pop si
        pop dx
        pop cx
        pop bx
        pop ax
ret

               
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 14:47:03 | 显示全部楼层
这个程序多次改写了ES,然后和关于show_str子程序 后面那个当执行到0就结束子程序^
如果table段中不是从小到大的数值的话,就是一个bug。
不知道这样对不对呢。
现在在改进这个程序,想用栈段来存储,或直接覆盖到data段中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 15:21:28 | 显示全部楼层
额,看了汇编网一个人的用栈存取数据的方法也不错。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 15:22:20 | 显示全部楼层
assume cs:code   

data segment   
  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514  
  dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000  
data ends   

stack segment  
   db 32 dup(0)  
stack ends

code segment
start:
                mov ax,data
                mov ds,ax
                mov ax,stack
                mov ss,ax
                mov sp,32
               
                mov di,0
                mov bl,0
                mov cx,21
dd_data:
        push cx
                mov ax,[di]                        ;将DD数据低16位给ax
                mov dx,[di+2]                ;将DD数据高16位给dx
                call dtoc
               
                mov dh,6
                add dh,bl
                mov dl,3
                mov cl,2
                call show_str
               
                add di,4
                inc bl
        pop cx
                loop dd_data
               
                mov ax,4c00h
                int 21h
dtoc:
        push ax
        push cx
        push si
        push bp
                mov si,0                ;记录数据位数
s1:       
                mov cx,10                ;(cx)=除数
                call divdw
                add cx,30h                ;(cx)=ASCII码
                push cx                        ;将ASCII码推入栈中
                add si,1               
                mov cx,ax                ;将int(X/N)给cx
                jcxz ok
                jmp s1
ok:
                mov bp,0                ;ss:bp用来存储DD数据的ASCII码
                mov cx,si                ;将数据位数给cx
s2:
                pop ax                        ;(ax)=(ss:sp)
                mov [bp],al                ;(ss:bp)=(ss:sp)
                inc bp
                loop s2
                mov byte ptr [bp],0
        pop bp
        pop si
        pop cx
        pop ax
ret
               
divdw:
        push bx
                push ax                        ;将低16位数据暂存栈中
                mov ax,dx                ;将高16位数据给ax
                mov dx,0                ;将余数清零避免干扰下面运算
                div cx                        ;计算int(H/N)
                mov bx,ax                ;将int(H/N)暂存bx中
                pop ax                        ;将低16位数据出栈给AX
                div cx                        ;计算(L+rem(H/N)*65536)/N
                mov cx,dx                ;将余数给cx
                mov dx,bx                ;将结果高16位给dx
        pop bx
ret

show_str:
        push ax
        push bx
        push cx
        push dx
        push bp
                mov ax,0b800h
                mov es,ax
               
                mov al,160                        ;以下计算显示缓冲区的偏移地址
                dec dh
                mul dh
                mov bx,ax
               
                mov al,2
                mul dl
                sub dl,2
               
                add bx,ax                       
               
                mov bp,0
                mov ah,cl
s:
                mov ch,0                       
                mov cl,[bp]                       
                jcxz return
                mov al,[bp]                       
                mov es:[bx],ax               
                inc bp                               
                add bx,2                       
                jmp s
return:
        pop bp
        pop dx
        pop cx
        pop bx
        pop ax
ret
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 15:23:18 | 显示全部楼层
本帖最后由 ling7 于 2012-2-24 15:23 编辑

这是改进的。。也不用什么大的改动……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 15:29:52 | 显示全部楼层
接下来把全部完成试试……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 18:03:53 | 显示全部楼层
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,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  

stack segment  
   db 32 dup(0)  
stack ends  

code segment   
start:
                mov ax,data
                mov ds,ax
                mov ax,stack
                mov ss,ax
                mov sp,32
               
                mov di,0                ;读取数据起始偏移地址
                mov bl,0                ;行数变量
                mov cx,21                ;循环次数
;年份               
dd_data:
                push cx
                mov cx,4
                mov bp,0
s0:
                mov al,[di]
                mov [bp],al
                inc di
                inc bp
                loop s0
                mov byte ptr [bp],0
               
                mov dh,5
                add dh,bl
                mov dl,23
                mov cl,2
                call show_str
                pop cx
                inc bl
                loop dd_data
;收入
                mov cx,21
                mov bl,0
                mov di,84
dd_data1:
                push cx
                mov ax,[di]
                mov dx,[di+2]
                call dtoc
                mov dh,5
                add dh,bl
                mov dl,33
                mov cl,2
                call show_str
                pop cx
                inc bl
                add di,4
                loop dd_data1
;人数
                mov cx,21
                mov bl,0
                mov di,168
dd_data2:
                push cx
                mov ax,[di]
                mov dx,0
                call dtoc
                mov dh,5
                add dh,bl
                mov dl,43
                mov cl,2
                call show_str
                pop cx
                inc bl
                add di,2
                loop dd_data2
               
;人均工资
                mov cx,21
                mov bl,0
                mov di,84
                mov si,168
dd_data3:
                push cx
                mov ax,[di]
                mov dx,[di+2]
                div word ptr [si]
                mov dx,0
                call dtoc
                mov dh,5
                add dh,bl
                mov dl,53
                mov cl,2
                call show_str
                pop cx
                inc bl
                add di,4
                add si,2
                loop dd_data3
               
                mov ax,4c00h
                int 21h
               
dtoc:
        push ax
        push cx
        push bp
        push si
                mov si,0
       
s1:        mov cx,10
                call divdw
                add cx,30h
                push cx
                inc si
                mov cx,ax
                jcxz ok
                jmp s1
ok:
                mov bp,0
                mov cx,si
s2:
                pop ax
                mov [bp],al
                inc bp
                loop s2
                mov byte ptr [bp],0
        pop si
        pop bp
        pop cx
        pop ax
ret

divdw:
        push bx
                push ax                        ;将低16位数据暂存栈中
                mov ax,dx                ;将高16位数据给ax
                mov dx,0                ;将余数清零避免干扰下面运算
                div cx                        ;计算int(H/N)
                mov bx,ax                ;将int(H/N)暂存bx中
                pop ax                        ;将低16位数据出栈给AX
                div cx                        ;计算(L+rem(H/N)*65536)/N
                mov cx,dx                ;将余数给cx
                mov dx,bx                ;将结果高16位给dx
        pop bx
ret

show_str:
        push ax
        push bx
        push cx
        push dx
        push bp
                mov ax,0b800h
                mov es,ax
               
                mov al,160                        ;以下计算显示缓冲区的偏移地址
                dec dh
                mul dh
                mov bx,ax
               
                mov al,2
                mul dl
                sub dl,2
               
                add bx,ax
               
                mov bp,0
                mov ah,cl
s:
                mov cl,[bp]
                mov ch,0
                jcxz return
                mov al,[bp]
                mov es:[bx],ax
                add bx,2
                inc bp
                jmp s
return:
        pop bp
        pop dx
        pop cx
        pop bx
        pop ax
ret
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-24 18:04:15 | 显示全部楼层
本帖最后由 ling7 于 2012-2-24 18:06 编辑

呼  累死我了。  终于写出来了
子程序前两个参考了小甲鱼老师的,栈的思路参考了汇编网mouse作者的思路
受益匪浅呀……不过也最终写完了。
终于可以下一章。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-10-8 12:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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