|
主题 : : 课程设计1终于完成了~~~~ [待解决] |
回复[ 12次 ]
点击[ 781次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2010-01-27 14:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37 |
自学汇编一个多月了吧!课程设计1终于完成了!
开始时思路不是很清晰,想了几个思路,都不系统,而且没办法对一个子程序多次调用,因为,每次调用子程序,都必须对子程序做一定的修改,没办法模块化!
后天在论坛上看到asm_sande的思路后,才开始了自己的设计,写完一个程序很快,不到一个小时吧,可是调试却让我很伤脑筋,先是不能编译,能编译后没有结果显示,想一步一步的跟踪,可是循环次数太多,最后,我把循环次数都改为一次,一步一步的跟踪,才完成了这个课程设计!
我觉得学汇编最重要的就是调试,在自己的调试过程中,慢慢的知道什么地方是自己容易忽视的地方,比如寄存器的冲突,栈的使用,深入理解计算机处理数据的过程,这次我才发现了对自己写的程序做注释的好处,这样不仅能把自己的思路系统一下,而且以后看到自己的程序也会很清楚的知道是什么作用!!(说了些废话)
大家多提点建议吧~~
assume cs:code,ds:data,ss:stack
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,15275,17800
data ends
table segment
db 672 dup (0)
table ends
stack segment
dw 32 dup (0)
stack ends
code segment
start:mov ax,data
mov ds,ax ;ds指向data
mov ax,table
mov es,ax ;es指向table
mov ax,stack
mov ss,ax ;ss指向stack
mov sp,20h ;sp指向栈顶
mov bx,0 ;写入时寻址增量
mov di,0 ;读取时双字增量
mov si,0 ;读取时单字增量
mov cx,21 ;循环次数
d:push ds:[di]
push ds:[di+2]
pop es:[bx+2]
pop es:[bx] ;转移年份
mov byte ptr es:[bx+4],0 ;末尾标识符
mov ax,ds:[di+54h] ;ax 被除数低位
mov dx,ds:[di+56h] ;dx 被除数高位
mov es:[bx+7],dx
mov es:[bx+5],ax ;转移总量
push cx
mov cx,ds:[si+0a8h] ;cx 除数
mov es:[bx+16],cx ;转移人数
call divdw ;调用divdw
pop cx
mov es:[bx+22],ax ;平均数低位入table
mov es:[bx+24],dx ;平均数高位入table
add di,4
add si,2
add bx,32 ;增量
loop d ;循环
mov bx,0
mov cx,21 ;循环次数
e:mov ax,es:[bx+5]
mov dx,es:[bx+7]
mov di,5
add di,bx
call dtoc ;总量化为ASCII码
mov ax,es:[bx+16]
mov dx,0
mov di,16
add di,bx
call dtoc ;人数化为ASCII码
mov ax,es:[bx+22]
mov dx,es:[bx+24]
mov di,22
add di,bx
call dtoc ;平均值化为ASCII码
add bx,32 ;增量
loop e ;循环
mov cx,21 ;循环次数
mov di,0
mov dh,2 ;行
f:mov dl,4 ;列
push cx ;因为下面要用的cl保存属性,所以cx入栈
mov cl,2 ;属性:绿色
mov si,0
add si,di ;在es中读取年份
call show_str ;调用show_str
mov dl,20
mov cl,2
mov si,5
add si,di
call show_str
mov dl,40
mov cl,2
mov si,16
add si,di
call show_str
mov dl,60
mov cl,2
mov si,22
add si,di
call show_str
pop cx
add di,32 ;增量,读取下一条
inc dh ;行加1
loop f
mov ah,01h ;中断
int 21h
mov ax,4c00h
int 21h
divdw:push bx ;入参ax被除数低位,dx被除数高位,cx除数
push di
mov bp,ax
mov ax,dx
mov dx,0
div cx
mov di,ax
mov ax,bp
div cx
mov cx,dx
mov dx,di ;回参ax商低位,dx商高位
pop di
pop bx
ret
dtoc:push bx
push cx
push si ;子程序中使用的寄存器入栈
mov si,0
a:mov cx,10 ;除数
call divdw
add cx,30h
push cx
inc si
mov cx,ax
jcxz b
jmp short a
b:mov cx,si ;cx中储存循环次数
mov bx,0
c:pop es:[bx+di]
inc bx ;后来出栈的数据的低16为把前面出栈的高16为覆盖
loop c
pop si
pop cx
pop bx ;子程序中使用的寄存器出栈
ret
show_str:push dx
push bx
push cx
mov ax,0B800H
mov ds,ax ;es指向显示缓冲区
dec dh
mov al,0a0h
mul dh
dec dl
add dl,dl
mov dh,0
add ax,dx
mov bx,ax ;计算偏移地址
mov ah,cl ;ah暂时储存颜色
s:mov cl,es:[si];字符放在cl中
mov ch,0
jcxz ok ;判断是否结束
mov ch,ah ;颜色放在ch中
mov ds:[bx],cx;放于显示缓存区
add bx,2
inc si ;计数增加
jmp short s ;跳转
ok:pop cx
pop bx
pop dx
ret
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2010-01-27 14:21 ]
[引用]
[回复]
[ top ] | |
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14 |
引用:
我觉得学汇编最重要的就是调试
------------------------------------------
调试了才能充分的理解掌握,别人说的未必能让自己很好的消化,加油^-^ | | |
|
|
|
|
[第2楼]
[ 回复时间:2010-01-27 15:00 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37 |
回复:[第1楼]
------------------
说的对啊,呵呵,大家一起努力 | | |
|
|
|
|
[第3楼]
[ 回复时间:2010-01-30 12:25 ]
[引用]
[回复]
[ top ] | |
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51 |
|
|
|
|
|
[第4楼]
[ 回复时间:2010-01-30 18:50 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37 |
回复:[第3楼]
------------------
呵呵,你比我学的细致,经常在论坛上看到你的评论~~ | | |
|
|
|
|
[第5楼]
[ 回复时间:2010-01-30 23:49 ]
[引用]
[回复]
[ top ] | |
荣誉值:61
信誉值:0
注册日期:2009-12-19 01:51 |
回复:[第3楼]
------------------
呵呵,你比我学的细致,经常在论坛上看到你的评论~~
------------------
回复:⊙﹏⊙b汗, 无地自容一下先。。。 | | |
|
|
|
|
[第6楼]
[ 回复时间:2010-02-01 04:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18 |
|
|
|
|
|
[第7楼]
[ 回复时间:2010-02-05 07:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18 |
|
|
|
|
|
[第8楼]
[ 回复时间:2010-02-05 07:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18 |
|
|
|
|
|
[第9楼]
[ 回复时间:2010-02-05 11:05 ]
[引用]
[回复]
[ top ] | |
荣誉值:4
信誉值:6
注册日期:2010-01-07 10:37 |
回复:[第7楼]
------------------
我认为应该可以,最好在实dos下试试 | | |
|
|
|
|
[第10楼]
[ 回复时间:2010-02-06 07:24 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18 |
总算完成了贴出来吧高手指点
assume cs:code,ds:data,ss:stack
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,15275,17800
data ends
table segment
db 672 dup (0)
table ends
stack segment
dw 32 dup (0)
stack ends
code segment
start:mov ax,data
mov ds,ax
mov ss,ax
mov ax,0
mov sp,ax
mov ax,table
mov es,ax
call show_str1
call show_str2
call show_str3
call quyu
call show_str4
mov ax,4c00h
int 21h
show_str1:push ax
push bx
push cx
push dx
mov ax,0
mov dx,0
mov bx,0
mov cx,21
d: mov ax,ds:[bx]
push ax
pop es:[bx+2]
mov ax,ds:[bx+2]
push ax
pop es:[bx+4]
mov ax,0
mov ds:[bx],ax
mov ds:[bx+2],ax
add bx,4
loop d
mov cx,21
mov bx,0
mov dh,2 ;显示坐标一定要放在loop之前
mov dl,2
e: mov ax,es:[bx+2]
push ax
mov ax,es:[bx+4]
push ax
pop ds:[2]
pop ds:[0]
push cx
mov cx,02h
call show_str
pop cx
add bx,4
inc dh
loop e
pop dx
pop cx
pop bx
pop ax
ret
show_str2:push ax
push bx
push bp
push cx
push dx
mov ax,0
mov dx,0
mov bx,0
mov dh,2 ;显示坐标一定要放在loop之前
mov dl,20
mov cx,21
f: mov bp,dx
mov ax,ds:[bx+84]
mov dx,ds:[bx+86]
call dtoc
mov dx,bp
push cx
mov cx,02h
call show_str
pop cx
add bx,4
inc dh
loop f
pop dx
pop cx
pop bp
pop bx
pop ax
ret
show_str3:push ax
push bx
push bp
push cx
push dx
mov ax,0
mov dx,0
mov bx,0
mov dh,2 ;显示坐标一定要放在loop之前
mov dl,40
mov cx,21
g: mov bp,dx
mov ax,ds:[bx+168]
mov dx,0
call dtoc
mov dx,bp
push cx
mov cx,02h
call show_str
pop cx
add bx,2
inc dh
loop g
pop dx
pop cx
pop bp
pop bx
pop ax
ret
show_str4:push ax
push bx
push bp
push cx
push dx
mov ax,0
mov dx,0
mov bx,0
mov dh,2 ;显示坐标一定要放在loop之前
mov dl,60
mov cx,21
t: mov bp,dx
mov ax,es:[bx+186]
mov dx,es:[bx+188]
call dtoc
mov dx,bp
push cx
mov cx,02h
call show_str
pop cx
add bx,4
inc dh
loop t
pop dx
pop cx
pop bp
pop bx
pop ax
ret
quyu: push ax
push bx
push di
push bp
push cx
push dx
mov di,0
mov dx,0
mov bx,0
mov cx,21
x: mov bp,cx
mov ax,ds:[bx+84]
mov dx,ds:[bx+86]
mov cx,ds:[di+168]
call div_str
mov es:[bx+186],ax
mov es:[bx+188],dx
mov cx,bp
add bx,4
add di,2
loop x
pop dx
pop cx
pop bp
pop di
pop bx
pop ax
ret
dtoc: push di
push ax
push bx
push si
push bx
push cx
a: mov cx,dx
jcxz goon ;判断dx高位是否为0
mov cx,0ah
call div_str
push cx
inc si
jmp short a
goon:mov cx,ax
jcxz re_num
mov cx,0ah
call div_str
push cx
inc si
jmp short goon
re_num: mov cx,si
s: pop ax
mov bx,30h
add ax,bx
mov ds:[di],ax
inc di
loop s
pop cx
pop bx
pop si
pop bx
pop ax
pop di
ret
div_str:push bx
push ax
mov ax,dx
div cl
mov bx,ax
mov ah,0
mov dx,ax
pop ax
push dx
mov dx,bx
mov dl,dh
mov dh,0
div cx
mov cx,dx
pop dx
pop bx
ret
show_str: push di
push si
push dx
push bx
push es ;注意ss:sp指向长度
dec dh ;送入变量dh行号,dl为排号注意寄存器的使用cl为颜色
dec dl
mov ax,0
mov al,dh
mov bx,0
mov bl,10
mul bl
mov bx,ax
mov ax,0b800h
add ax,bx
mov es,ax
mov ax,0
mov al,dl
add al,dl
mov bx,ax
mov di,0
mov ch,cl
ok: mov cl,[si]
push cx
mov ch,0
jcxz return
pop cx
mov es:[bx+di],cx
add di,2
inc si
jmp short ok
return: pop cx
pop es
pop bx
pop dx
pop si
pop di
ret
code ends
end start | | |
|
|
|
|
[第11楼]
[ 回复时间:2010-02-06 07:38 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18 |
55结果出错了,郁闷啊!!又要debug32了!!!要走的路很长哇!! | | |
|
|
|
|
[第12楼]
[ 回复时间:2010-02-07 23:16 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-10-07 14:18 |
找到原因了子程序div_str的问题改成这样就OK了不影响
div_str:push bx
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax
pop ax
push bx
div cx
mov cx,dx
pop dx
pop bx
ret | | |
|