| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1975 人关注过本帖
标题:王爽汇编语言课程设计一搞定,总觉得自己的代码风格不好。求指导
只看楼主 加入收藏
chaoc
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2012-10-20
结帖率:71.43%
收藏
已结贴  问题点数:5 回复次数:13 
王爽汇编语言课程设计一搞定,总觉得自己的代码风格不好。求指导
不知道汇编推崇什么编码风格,以前学C语言的风格没什么指导意义。
怎么命名,函数参数使用寄存器传递,还是压栈传递。等等都是我现在纠结的问题。真希望有一本想代码大全的书说一下汇编的编程风格。

代码写的很原始,居然有497行


这个课程设计题目卡了我4天了。

图片附件: 游客没有浏览图片的权限,请 登录注册

代码贴到楼下,希望有人能指导一下我的代码风格问题。

[ 本帖最后由 chaoc 于 2012-10-24 16:11 编辑 ]
搜索更多相关主题的帖子: 寄存器 风格 C语言 
2012-10-24 16:09
chaoc
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2012-10-20
收藏
得分:0 
程序代码:
;这是王爽《汇编语言》课程设计 1
;将实验7中的Power idea公司的数据以一定格式显示在屏幕上
;作者ID:chaoc
;时间:21:14  2012/10/22~2012/10/24...

assume cs:code,ss:stack
stack segment
    dd 8 dup(0)
stack ends

Year segment;每个年份为4个byte
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
Year ends

;..................................................................................................
Income segment;每年的收入为一个dword型数据,即4个字节
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000
        dd 5937000
Income ends

IncomeStr segment
          db 21 dup('        ');8个字符 字节
IncomeStr ends
;..................................................................................................


;..................................................................................................
Employees segment;每年的员工人数为一个word型数据,即2个byte,此段占48个字节
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037
        dw 5635,8226,11542,14430,15257,17800
Employees ends

EmployeesStr segment
            db 21 dup('     ');5个字符 字节 此段占112个字节
EmployeesStr ends
;..................................................................................................


;..................................................................................................

Perincome segment
    dw 21 dup(32)
Perincome ends

PerincomeStr segment
    db 21 dup('   ');3个字符,字节
PerincomeStr ends
;..................................................................................................

Lable segment
    db ' Year       Income  Employees Perincome'
Lable ends

code segment
    start:
            mov ax,stack
            mov ss,ax
;        step0:计算人均收入
            mov ax,Income             ;把收入设为数据段ds +si
            mov ds,ax
            mov ax,Employees            ;把员工人数设为扩展段es+di
            mov es,ax
            mov si,0
            mov di,0
           
            mov cx,21
            loop0:
            push cx
            mov dx,ds:[si+2]
            mov ax,ds:[si]
            mov cx,es:[di]
            push dx
            push ax
            push cx
            call divdw
            mov es:[di+160],ax;把人均收入设为es段 es+di+160
            add si,4
            add di,2
            pop cx
            loop loop0
           
;        step1:把Income段中的数据转为字符串保存到IncomeStr段。注意IncomeStr中的结果都是逆序的。
            mov ax,Income;把Income设为数据段 ds+si
            mov ds,ax
            mov ax,IncomeStr;把IncomStr设为扩展段es+di
            mov es,ax
            mov si,0
            mov di,0
           
            mov cx,21
            loop1:
            mov ax,ds:[si+2];依次将每个dword数据的高16位压栈
            push ax
            mov ax,ds:[si];低16位
            push ax
            push es            ;存放转换结果字符的扩展段地址入栈
            push di        ;存放字符的偏移地址入栈
            call dtoc
            add si,4
            add di,8
            loop loop1
       
;        step2:把Employees段中的数据转为字符串保存到EmployesStr段。注意EmployeesStr中的结果都是逆序的。
            mov ax,Employees;把Employees设为数据段 ds+si
            mov ds,ax
            mov ax,EmployeesStr;把EmployeesStr设为扩展段es+di
            mov es,ax
            mov si,0
            mov di,0
           
            mov cx,21
            loop2:
            mov ax,ds:[si];依次将每个word数据压栈
            push ax
            push es            ;存放转换结果字符的扩展段地址入栈
            push di        ;存放字符的偏移地址入栈
            call wtoc
            add si,2
            add di,5
            loop loop2   
           
;        step3:把Perincome段中的数据转为字符串保存到PerincomeStr段。注意PerincomeStr中的结果都是逆序的。
            mov ax,Perincome;把Perincome设为数据段 ds+si
            mov ds,ax
            mov ax,PerincomeStr;把PerincomeStr设为扩展段es+di
            mov es,ax
            mov si,0
            mov di,0
           
            mov cx,21
            loop3:
            mov ax,ds:[si];依次将每个word数据压栈
            push ax
            push es            ;存放转换结果字符的扩展段地址入栈
            push di        ;存放字符的偏移地址入栈
            call wtoc
            add si,2
            add di,3
            loop loop3   
           
;        step4:把IncomeStr,EmployeesStr,PerincomeStr段的数据翻转变为正序
;            step4.1把IncomeStr段的数据转为正序
            mov ax,IncomeStr
            mov ds,ax
            mov si,0
            mov ax,8
            mov cx,21
            step4loop1:
            push ds
            push si
            push ax
            call ReverseStr
            add si,8
            loop step4loop1
;            step4.2把EmployeesStr段的数据转为正序
            mov ax,EmployeesStr
            mov ds,ax
            mov si,0
            mov ax,5
            mov cx,21
            step4loop2:
            push ds
            push si
            push ax
            call ReverseStr
            add si,5
            loop step4loop2
;            step4.3把PerincomeStr段的数据转为正序
            mov ax,PerincomeStr
            mov ds,ax
            mov si,0
            mov ax,3
            mov cx,21
            step4loop3:
            push ds
            push si
            push ax
            call ReverseStr
            add si,3
            loop step4loop3
                       
           
;        step5:把数据显示到屏幕上,即把表格数据发送到显示缓冲区
;            step5.0在显示数据前先清屏
            call clear
           
;            step5.1把年份发送到显示缓冲区
            mov ax,Year
            mov ds,ax
            mov si,0 ;要显示的字符首地址
            mov dl,1 ;列号
            mov dh,4 ;行号
            mov bh,4 ;字符个数
            mov bl,00000010B;颜色
            mov cx,21
            step5loop1:
            push dx
            push bx
            push ds
            push si
            call showstr
            inc dh
            add si,4
            loop step5loop1
;            step5.2把总收入IncomeStr段的数据发送到显示缓冲区
            mov ax,IncomeStr
            mov ds,ax
            mov si,0 ;要显示的字符首地址
            mov dl,10 ;列号
            mov dh,4  ;行号
            mov bh,8 ;字符个数
            mov bl,00000100B;颜色
            mov cx,21
            step5loop2:
            push dx
            push bx
            push ds
            push si
            call showstr
            inc dh
            add si,8
            loop step5loop2
;            step5.3把员工人数即EmpoyeesStr段的数据发送显示缓冲区
            mov ax,EmployeesStr
            mov ds,ax
            mov si,0 ;要显示的字符首地址
            mov dl,20 ;列号
            mov dh,4  ;行号
            mov bh,5 ;字符个数
            mov bl,00000001B;颜色
            mov cx,21
            step5loop3:
            push dx
            push bx
            push ds
            push si
            call showstr
            inc dh
            add si,5
            loop step5loop3
;            step5.4把人均收入即PerincomeStr段的数据发送到显示缓冲区
            mov ax,PerincomeStr
            mov ds,ax
            mov si,0 ;要显示的字符首地址
            mov dl,30 ;列号
            mov dh,4  ;行号
            mov bh,3 ;字符个数
            mov bl,00000101B;颜色
            mov cx,21
            step5loop4:
            push dx
            push bx
            push ds
            push si
            call showstr
            inc dh
            add si,3
            loop step5loop4
;            step6:在数据的最前面显示栏目标签
            mov ax,Lable
            mov ds,ax
            mov si,0
            mov dl,0
            mov dh,2
            mov bl,00000010B
            mov bh,40
           
            push dx
            push bx
            push ds
            push si
            call showstr
           
            ;主函数结束
            mov ax,4c00h
            int 21h
;............................................................................................................................................................
;............................................................................................................................................................
;...........................................................上面是主程序.....................................................................................
;..........................................................下面是要调用的几个函数............................................................................
;............................................................................................................................................................
;............................................................................................................................................................
    divdw:    push bp
                push bx
                mov bp,sp
                   
                mov cx,[bp+6];除数
                mov ax,[bp+10];高16位
                mov dx,0
                div cx;现在AX中是高16位除n的商,DX中是余数
                push ax;把高16位的除到得商保存到栈里
               
                mov ax,[bp+8];现在dx中是高16位除到的余数,ax中是低16位
                div cx
                mov cx,dx
                pop dx;现在dx中时高16除到得商,ax中是低16位除到得商,cx中是余数
               
                pop bx
                pop bp
                ret 6
        ;divdw函数结束
    dtoc:       
                push ax
                push bx
                push cx
                push ds
                push si
                push bp
                mov bp,sp
               
                mov dx,[bp+20];数据的高16位
                mov ax,[bp+18];数据的低16位
                mov ds,[bp+16];段地址
                mov si,[bp+14];偏移地址
               
            dtocs1:
                push dx
                push ax
                mov cx,10
                push cx
                call divdw
                add cx,30H
                mov ds:[si],cl;把转换后的字符送到指定的数据区域
                add si,1
                mov cx,ax
                jcxz dtoctestagain;判断商的低16位是不是0
            dtocs2:
                mov cx,10
                jmp dtocs1
              dtocwordsend:   
                  pop bp
                  pop si
                  pop ds
                  pop cx
                  pop bx
                  pop ax
                  ret 8
          dtoctestagain:
                  mov cx,dx;判断商的低16位后再判断商的高16位是不是0
                  jcxz dtocwordsend;如果都是0就跳到wordsend,准备跳除函数
                  jmp dtocs2;不是0回到前面继续执行
          ;函数dtoc结束
          wtoc:       
                push ax
                push bx
                push cx
                push ds
                push si
                push bp
                mov bp,sp
               
                mov dx,0            ;数据的高16位
                mov ax,[bp+18];数据的低16位
                mov ds,[bp+16];段地址
                mov si,[bp+14];偏移地址
               
            wtocs1:
                push dx
                push ax
                mov cx,10
                push cx
                call divdw
                add cx,30H
                mov ds:[si],cl;把转换后的字符送到指定的数据区域,转换后的字符只占据cl
                add si,1
                mov cx,ax
                jcxz wtocwordsend
                mov cx,10
                jmp wtocs1
              wtocwordsend:   
                  pop bp
                  pop si
                  pop ds
                  pop cx
                  pop bx
                  pop ax
                  ret 6
   ;wtoc函数结束
  
       showstr:   
                push ax
                push bx
                push cx
                push dx
                push ds
                push es
                push si
                push di
                push bp
               
                mov bp,sp
                mov dx,[bp+26];行号dh,列号dl
                mov bx,[bp+24];bl颜色值,bh个数
                mov ds,[bp+22];段地址
                mov si,[bp+20];偏移
               
                mov di,0H;屏幕的偏移
                ;接下来计算行号和列号带来的偏移di的初值
                push bx;bx寄存器要用到
                mov al,dh;开始计算行号带来的偏移
                mov ah,0
                mov bl,160
                mul bl
                add di,ax;把计算行号带来的偏移值加到di上
                mov al,dl;开始计算列号带来的偏移
                mov ah,0
                mov bl,2
                mul bl
                add di,ax;把计算列号带来的偏移加到di上
                pop bx;恢复bx的值
               
                mov ax,0B800H;显示缓冲区的起始地址
                mov es,ax
               
                mov ch,0
                mov cl,bh          ;把bh的值复制给cl用作循环次数
                showstrloop:
                mov bh,ds:[si]    ;这里bh为要显示的字符了
                mov es:[di],bh
                mov es:[di+1],bl    ;颜色值
                inc si
                add di,2
                loop showstrloop
                   
                pop bp
                pop di
                pop si
                pop es
                pop ds
                pop dx
                pop cx
                pop bx
                pop ax
                ret 8
    ;show_str ends
    ReverseStr:
        push ax
        push ds
        push si
        push cx
        push bp
       
        mov bp,sp
       
        mov ds,[bp+16];取得3个参数
        mov si,[bp+14]
        mov cx,[bp+12]
       
        ReverseStrloop1:;把字符串取出来,存到栈中,再出栈实现顺序逆转
        mov al,ds:[si] ;字符串中的字符是byte型。用word装住它再压栈
        push ax
        inc si
        loop ReverseStrloop1
       
        mov cx,[bp+12] ;由于cx和si的值在上面已经改变,现在须重新赋值
        mov si,[bp+14]
        ReverseStrloop2:
        pop ax          ;依次出栈,实现逆序
        mov ds:[si],al
        inc si
        loop ReverseStrloop2
       
        pop bp
        pop cx
        pop si
        pop ds
        pop ax
       
        ret 6
        ;函数ReverseStr结束
        clear:
        push ds
        push si
        push ax
        push cx
       
        mov ax,0B800H
        mov ds,ax
        mov si,0
        mov cx,0FFFFH;25*80的缓冲区,2000个字符
        clearloop:
        mov ax,0000011100100000b
        mov ds:[si],ax
        add si,2
        loop clearloop
       
        pop cx
        pop ax
        pop si
        pop ds
        ret
        ;clear函数结束
code ends
end start
2012-10-24 16:12
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
算不错哦 给个颜色吧
代码有注释 层次清晰 容易阅读就是好的 至于风格我也说不上来 呵呵。

梅尚程荀
马谭杨奚







                                                       
2012-10-24 17:09
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:3 
汇编的语法可以说是非常简单 组成程序的就是指令 而指令的格式就那么几个 所以只要缩进处理好了就很好了

非要说格式的话
程序代码:
stack segment
    dd 8 dup(0)
stack ends

Year segment;每个年份为4个byte
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
Year ends

;..................................................................................................
Income segment;每年的收入为一个dword型数据,即4个字节
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000
        dd 5937000
Income ends

IncomeStr segment
          db 21 dup('        ');8个字符 字节
IncomeStr ends
;..................................................................................................


;..................................................................................................
Employees segment;每年的员工人数为一个word型数据,即2个byte,此段占48个字节
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037
        dw 5635,8226,11542,14430,15257,17800
Employees ends

EmployeesStr segment
            db 21 dup('     ');5个字符 字节 此段占112个字节
EmployeesStr ends

这里 大家都是段 为啥开头的缩进不一样呢 当然这也可能是编辑器的问题 不过要是统一的话 应该是不会出现这个问题啊。。

还有就是 因为汇编是没有结构化语言的三大结构的 所以这个结构的实现需要编程者自己控制 这样的话 良好的缩进对代码的可读性有很大的帮助 一个例子
程序代码:
            loop0:
            push cx
            mov dx,ds:[si+2]
            mov ax,ds:[si]
            mov cx,es:[di]
            push dx
            push ax
            push cx
            call divdw
            mov es:[di+160],ax;把人均收入设为es段 es+di+160
            add si,4
            add di,2
            pop cx
            loop loop0

如果这里面的东西是缩进的 我一看就知道 这中间的代码是个循环 这样不比我还要通过指令来认识来的快么

楼主如果感兴趣 可以把这个代码整理一下加加注释 可能会有很大的收获哦 那样的话给个精华也可以嘛

祝楼主学习顺利



[ 本帖最后由 zklhp 于 2012-10-24 17:43 编辑 ]
2012-10-24 17:36
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
再有就是 楼主能写这么长的代码好厉害啊 我估计是写不了 呵呵
2012-10-24 17:45
chaoc
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2012-10-20
收藏
得分:0 
回复 5楼 zklhp
做课程设计1应该都有这么长吧?
我应该是自己实现了已有的东西所以才这么长。
2012-10-24 17:49
chaoc
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2012-10-20
收藏
得分:0 
回复 4楼 zklhp
“段的缩进要一样”,你是说的
要这样
程序代码:
Year segment;每个年份为4个byte
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
Year ends

不要这样吗?
程序代码:
Year segment;每个年份为4个byte
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
Year ends

2012-10-24 17:53
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
以下是引用chaoc在2012-10-24 17:53:46的发言:

“段的缩进要一样”,你是说的
要这样Year segment;每个年份为4个byte
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
Year ends
不要这样吗?Year segment;每个年份为4个byte
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
Year ends

不是啊 你没发现

程序代码:
stack segment
    dd 8 dup(0)
stack ends


程序代码:
Year segment;每个年份为4个byte
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
Year ends


为啥缩进不一样 哦 你可别说堆栈段比较特殊。。 大家都是段 都一样。。
2012-10-24 17:55
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:2 
不知道汇编推崇什么编码风格,以前学C语言的风格没什么指导意义。

还有就是 怎么没有指导意义 编程语言的基本思路是一样的 都是相通的 怎么能没意义呢 C语言的很多东西还是从汇编发展而来的呢 缩进肯定也是先在汇编上有了 然后再影响其他高级语言

比如 你肯定不会写
程序代码:

 int a;
    int b;
    while (1)
    {
a = 5;
    }

这样的代码罢

基本规范是一样的 只要你遵守了基本的规范就好了 至于以后什么团队开发有固定的要求神马的到时候再说罢 汇编也不大可能有这种开发。。 自己写都乱何况一群人一块写。。

要自己琢磨 不要指望有一本书都给你写好了 那有啥意思啊 多看代码 多思考


[ 本帖最后由 zklhp 于 2012-10-24 18:00 编辑 ]
2012-10-24 17:58
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
也许能精简点
如果按照罗云彬书上的来讲 最好在操作码和操作数之间用TAB间隔 TAB的大小可以自己定 推荐为8
函数名 和 函数体分开一下最好吧
其实找找几本经典的书上的代码比较下 能找到适合自己的风格吧
汇编代码最关键的是要让人读起来容易 舒服就好。

梅尚程荀
马谭杨奚







                                                       
2012-10-24 17:59
快速回复:王爽汇编语言课程设计一搞定,总觉得自己的代码风格不好。求指导
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.064680 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved