|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
【交流学习,共同进步】
【大家新年快乐啊!!!恭喜发财,红包拿来!!!!】
下面这个代码我敲了4个小时,头都大了,终于搞定了,不过还是存在很多可以优化的地方,有想法的小伙伴可以试试把我的代码优化一下哦!
还是那句话,我暂时没看小甲鱼老师的答案讲解。因为,只有不看答案,我的结题思路才会是全部原创的,哈哈哈哈。这样做出来的代码,才有更大的交流学习的价值。
- assume cs:code, ss:stack
- datasg 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个字符串,一共84个字节
-
- 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型的数据,一共84个字节
-
- 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个word型的数据,一共42个字节
- datasg ends
- data segment ;数据段默认用0结尾
- dw 24 dup(0)
- data ends
- stack segment ;我用了较多的栈空间,怕溢出,自己定义了一个栈
- dw 32 dup(0)
- stack ends
- code segment
- start: mov ax,stack ;初始化栈段
- mov ss,ax
- mov sp,32
- mov ax,data ;初始化数据段
- mov ds,ax
-
- mov ax,datasg ;初始化待转化的数据段
- mov es,ax
-
- mov si,0 ;si记录数据段记录的位置,永远指向结尾的0
- mov di,0 ;di记录待转化数据段的当前转化位置,低指向下一个待转化的地址,0是年份的开始,84是是总收入的起始,168是雇员人数的起始
-
- mov dh,2 ;提前定dh行数
-
-
-
-
- push es ;置零原先显存上第一页的数据,每一页显存4000个字节,从d8000h开始
- mov ax,0b800h
- mov es,ax
- mov ax,0
- mov cx,2000
- clear_gpu:
- mov es:[di],ax
- add di,2;
- loop clear_gpu
- pop es
- mov di,0
- mov cx,21
- dfg:
- push cx
- push dx
- mov si,0
- mov ax,es:[di] ;年份转入数据段
- mov ds:[si],ax
- mov ax,es:[di+1]
- mov ds:[si+1],ax
- mov ax,es:[di+2]
- mov ds:[si+2],ax
- mov ax,es:[di+3]
- mov ds:[si+3],ax
-
- mov ax,0 ;向字符串填入0结尾
- mov ds:[si+4],ax
-
- mov si,0 ;输出年份
- pop dx
- mov dl,12
- mov cl,2
- call show_str
- push dx
-
- mov ax,es:[di+84] ;总收入转化成acsell码转入数据段
- mov dx,es:[di+86]
- mov si,12 ;si指向总收入开始的地址,使其为12
- call dtoc_plus ;将ax和dx中的doubleword数据,变成字符串,记录在当前ds:【si】的位置,记录完成后si指向字符串末尾的0
- mov si,12 ;输出公司总收入
- pop dx
- mov dl,24
- mov cl,2
- call show_str
- push dx
-
- mov si,24 ;si指向总雇员开始的地址,使其为24
-
- push di ;di入栈保存,cx入栈保存
- push cx
-
- mov ax,di ;使di=二分之一的di
- mov cx,2
- mov dx,0
- div word ptr cx
- mov di,ax
- mov bp,ax ;额外用bp存放二分之一的di
-
- mov ax,es:[di+168] ;总雇员转化成acsell码转入数据段
- mov dx,0
- call dtoc_plus ;将ax和dx中的doubleword数据,变成字符串,记录在当前ds:【si】的位置,记录完成后si指向字符串末尾的0
-
- pop cx ;还原cx与di
- pop di
-
- mov si,24 ;输出雇员人数
- pop dx
- mov dl,36
- mov cl,2
- call show_str
- push dx
-
- mov ax,es:[di+84] ;计算人均收入的总收入
- mov dx,es:[di+86]
- mov cx,es:[bp+168]
- div word ptr cx
- mov dx,0
-
- mov si,36 ;si指向人均收入开始的地址,使其为12
- call dtoc_plus ;将ax和dx中的doubleword数据,变成字符串,记录在当前ds:【si】的位置,记录完成后si指向字符串末尾的0
-
- mov si,36 ;输出人均收入
- pop dx
- mov dl,48
- mov cl,2
- call show_str
-
-
- add di,4
- add dh,1
- pop cx
- dec cx
- jcxz yui
- jmp dfg
-
- yui: mov ax,4c00h
- int 21h
- ;将ax和dx中的doubleword数据用字符串的acsll码,记录在当前ds:【si】的位置,用0做结束,结束时si指向0所在位置
- dtoc_plus:
- push dx ;保留原函数的值
- push cx
- push ax
- push bx
-
- mov bx,0 ;先入栈一个0作为字符串的结尾
- push bx
-
- in_stack: ;处理dword数据的acsll值,并存入栈中
- mov cx,10
- call divdw ;dx被除数高16位,ax被除数低16位,cx除数,商的高16位在dx,低16位在ax,余数给cx
-
- add cx,30h ;acsll码值入栈
- push cx
-
- mov cx,dx ;双重检查,只有当ax和dx都是0才会通过
- inc cx
- loop in_stack
- mov cx,ax
- inc cx
- loop in_stack
-
- out_stack:
- pop ax ;栈里面是按word型存储的,但是,因为存进去的数不可能超过8位,所以只有low位有值,取al即可
- mov ds:[si],al
- inc si
- mov cx,ax
- inc cx
- loop out_stack
- dec si ;si回去一位,指向0
-
- pop bx
- pop ax
- pop cx
- pop dx
- ret
-
- ;dx被除数高16位,ax被除数低16位,cx除数,结果的高16位给dx,低16位给ax,余数给cx
- divdw:
- push bx ;保存可能变动的值
-
- push ax
- mov ax, dx ;高16位
- mov dx, 0 ; (新组合的32位的被除数)=0000 000fh
- div cx ;此时(dx)=余数 和 低16位 组合成一个新的32位的被除数
- mov bx, ax ;结果的高16位
- pop ax ;低16位
- div cx
- mov cx, dx ;余数
- mov dx, bx ;结果的高16位
-
- pop bx
- ret
- ;将dh看作行号(0-24),dl看作列号(0-79),cl看作颜色,
- ;ds:si指向字符串首地址,0为结束的字符串,放入显存指定位置,结束时si指向0所在位置
- show_str:
- push ax ;因为不知道主函数是否用了ax,先进栈保存,后续会使用ax寄存器
- push di ;因为不知道主函数是否用了di,先进栈保存,后续会使用di寄存器
- push es ;因为不知道主函数是否用了es,先进栈保存,后续会使用es寄存器
- push cx ;后面会对cx改动
- push dx
-
- mov ax,0b800h ;显存起始地址给es,用di记录位置
- mov es,ax
-
- mov di,0
-
- mov al,160 ;每行160个字节,每个字符2个字节,计算字节位置后,给di寄存器
- mul dh
- mov dh,0
- add ax,dx
- add ax,dx
- mov di,ax
-
- mov al,cl ;写入字符串
- mov ch,0
- read_in:
- mov cl,ds:[si]
- jcxz ok
- mov es:[di],cl
- mov es:[di+1],al
- add di,2
- inc si
- jmp short read_in
-
- ok: pop dx
- pop cx
- pop es
- pop di
- pop ax
- ret
- code ends
- end start
-
复制代码
还是发不了图,积分不够,不过我运行过了,是对的哦!
累了,累了,大家加油,好好学习,如果可以的话,帮我刷刷回帖,多顶顶,爱你们哦!
|
评分
-
查看全部评分
|