《王爽汇编》课程设计1
本帖最后由 leader4 于 2018-5-24 17:32 编辑课程设计1我终于做出来了,用了快一个星期了。。。总算是弄出了完全自主知识产权的代码。。
主要难点有两处:
1、对于子程序与参数分离的理解程度。
由于一开始没有弄明白这点,导致我的全部代码都是重新写的。。。之前练习用的子程序代码根本不可用。
其实真正写这个代码大概用了三天。。剩下四天其实都是在做前几个练习。。
2、程序整体思路。
其实如果把这个想明白了,其他就很好做了。
我一开始想的是:读取一个数据,转化为字符,在显示。然后循环完成。
但这样我写了很长时间,发现寄存器各种冲突,根本写不出来。。。
然后我换了一个思路,先把所有数据处理好,写入table段,然后在一起显示。
这一下就顺风顺水了。这之后,用了两个下午就写出来了。
其实第二个下午主要是找bug。。。
由于之前没有在每个子程序之前保存寄存器,结果还是有冲突的。。debug一步一步找出来才发现是寄存器的问题。。。。
之后就是显存写入有调试了一会儿,总算正常输出了!
插曲:当第一次写完程序编译运行没有得到想要的结果时,真是内心毫无波澜{:10_277:} 为什么一点也不感到意外呢~
补充:想用offset定位数据起始位置,结果google发现,数据标号居然不用冒号。。。
下面是代码,分享给初学者参考下。虽然参考价值可能不大。。:(注:我在mac上用的是dosbox,所以显存起始地址有些问题。。)
;===========================================================================
;课程设计1
;将实验7中的power idea公司的数据按照格式在屏幕上显示.
;===========================================================================
assume cs:codesg,ds:data,ss:stack,es:table
data segment
year db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
money dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
people dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
averagedw 21 dup (0)
;数据标号不用双引号。
data ends
table segment
db 21 dup (' year s n ? ',0)
; 1 9 17 24 算上0,共32个字符
table ends
stack segment
db 16 dup (0)
stack ends
codesg segment
start:
;年份入table段
mov ax,data
mov ds,ax
mov ax,offset year
mov si,ax ;data段首地址ds:si
mov ax,table
mov es,ax
mov di,1 ;table段首地址es:di
mov cx,21
year_table:
push cx
mov cx,2
mov bx,0
year_table0:
mov ax,
mov es:,ax
add bx,2
loop year_table0
add si,4
add di,32
pop cx
loop year_table
;--------------------------------
;收入入table
mov ax,data
mov ds,ax
mov si,offset money
mov ax,table
mov es,ax
mov di,9
mov cx,21
money_table:
mov bx,0
push cx
mov ax,
mov dx, ;显式给出参数
call dtoc
add si,4
add di,32
pop cx
loop money_table
;人数入table
mov ax,data
mov ds,ax
mov si,offset people
mov ax,table
mov es,ax
mov di,17
mov cx,21
people_table:
mov bx,0
push cx
mov ax,
mov dx,0 ;显式给出参数
call dtoc
add si,2
add di,32
pop cx
loop people_table
;平均数入table
mov ax,data
mov ds,ax
mov si,offset money
mov di,offset people
mov cx,21
s:
mov ax,
mov dx,
div word ptr
push ax
add si,4
add di,2
loop s
mov si,offset average
add si,40
mov cx,21
s1:
pop ax
mov ,ax
sub si,2
loop s1
;平均入table
mov si,offset average
mov ax,table
mov es,ax
mov di,24
mov cx,21
average_table:
mov bx,0
push cx
mov ax,
mov dx,0 ;显式给出参数
call dtoc
add si,2
add di,32
pop cx
loop average_table
;------------------------------
;将table段显示出来
mov ax,table
mov ds,ax
mov si,0
mov cx,21
mov dh,2
mov dl,0
table_show:
push cx
push dx
mov cl,2
call show_str
pop dx
add dh,1
pop cx
loop table_show
mov ax,4c00h
int 21h
;--------------------------------------------------
dtoc:
;参数
;(ax)=dword,低16位
;(dx)=dword,高16位
;ds:si指向字符串的首地址
;===============================
;保存寄存器
push ax
push bx
push cx
push dx
push si
push di
;===============================
mov bx,0
dtoc_j:
mov cx,10
call divdw
push cx
inc bx
mov cx,ax
jcxz dtoc_r
jmp dtoc_j
dtoc_r:
mov cx,bx
dtoc_l:
pop bx
add bx,30H
mov es:,bl
inc di
loop dtoc_l
;===============================
;恢复寄存器
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;-------------------------------------------
;-------------------------------------------
divdw:
;参数
;(ax)=dwrod,低16位
;(dx)=dword,高16位
;(cx)=除数
;返回
;(dx)=结果的高16位
;(ax)=结果的低16位
;(cx)=余数
;==========================
;保存寄存器
push si
push bx
;=========================
mov bx,ax
mov ax,dx
mov dx,0
div cx
push ax
mov ax,bx
div cx
mov cx,dx ;结果的余数
pop dx ;结果的高16位
;结果的低16位,默认在ax中。
;=========================
;恢复寄存器
pop bx
pop si
ret
;--------------------------------------
;--------------------------------------
show_str:
;参数
;(dh)=行号
;(dl)=列号
;(cl)=颜色
;======================
;======================
;计算行号
dec dh
mov ax,0a0h
mul dh
mov bx,ax
;计算列号
mov ax,2
mul dl
sub ax,2
;行号+列号
add ax,bx
;计算显存首地址
mov bx,8000h
add ax,bx
mov di,ax
mov ax,0b000h
mov es,ax
;写入数据
mov bl,cl
mov bp,0
show_str_s0:
mov al,ds:
mov es:,al
mov es:,bl
mov cl,
mov ch,0
jcxz show_str_s1
inc si
add bp,2
jmp short show_str_s0
show_str_s1:
inc si
ret
;======================
codesg ends
end start
我们都是一闪而过的,这个怎么让他停留可以截屏的呢?
页:
[1]