最近刚写完汇编实验十课设一的有木有?
如题。有的话 一起探讨一下的有吗?子程序都编好了,但是最后封装在一起的时候一直出现各种问题。
但是却说不上来是什么问题。
有写好的各位大大一起探讨下的有吗?
麻烦加我qq:448440520 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: ;将数据低16位数据给ax
mov dx,es: ;将数据高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 ,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, ;
jcxz return
mov al, ;将字符串ASCII码给al
mov es:,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 这个程序多次改写了ES,然后和关于show_str子程序 后面那个当执行到0就结束子程序^
如果table段中不是从小到大的数值的话,就是一个bug。
不知道这样对不对呢。
现在在改进这个程序,想用栈段来存储,或直接覆盖到data段中。 额,看了汇编网一个人的用栈存取数据的方法也不错。 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, ;将DD数据低16位给ax
mov dx, ;将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 ,al ;(ss:bp)=(ss:sp)
inc bp
loop s2
mov byte ptr ,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,
jcxz return
mov al,
mov es:,ax
inc bp
add bx,2
jmp s
return:
pop bp
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start 本帖最后由 ling7 于 2012-2-24 15:23 编辑
这是改进的。。也不用什么大的改动…… 接下来把全部完成试试…… 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,
mov ,al
inc di
inc bp
loop s0
mov byte ptr ,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,
mov dx,
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,
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,
mov dx,
div word ptr
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 ,al
inc bp
loop s2
mov byte ptr ,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,
mov ch,0
jcxz return
mov al,
mov es:,ax
add bx,2
inc bp
jmp s
return:
pop bp
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start 本帖最后由 ling7 于 2012-2-24 18:06 编辑
呼累死我了。终于写出来了
子程序前两个参考了小甲鱼老师的,栈的思路参考了汇编网mouse作者的思路
受益匪浅呀……不过也最终写完了。
终于可以下一章。
页:
[1]