|
20鱼币
很无语 单独调试显示“人均收入”函数没问题,但把另外三条函数加上去就不能显示 另外三条函数也是没问题的(单独调试)
好像两者水火不相容一样,我也看过条用每条函数后寄存器的变化了 都正常的 条用后都没改变寄存器值 真是见鬼了我 求大神啊
贴上源码assume cs:code,ds:data,ss:stack
怎么用上面那个贴源码?????算了 直接贴assume cs:code,ds:data,ss:stack
data segment ;数据段
string db 11 dup (0) ;字符串数据缓冲区
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'
;以上为年份
summ dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000
dd 5947000
;以上为收入
people dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635
dw 8226,11452,14430,15257,17800
;以上为人员数
data ends
stack segment ;栈空间段
db 1000 dup (0)
stack ends
code segment ;代码段
start: mov ax,stack
mov ss,ax
mov sp,1000
mov ax,data
mov ds,ax
call clear_asm ;清屏
;call show_year ;显示年份
;call show_people;显示员工
;call show_summ ;显示年收入
call show_Average;显示人均收入
;???为什么只调用此函数可以正常显示
;加上上面三条显示年份、员工、收入后就不显示了??
mov ax,4c00h
int 21h
;---------------------------------------------------------------
;函数功能:排版并显示人均收入
;函数参数:无
;函数返回:无
show_Average:
push ax
push bx
push cx
push dx
push si
push di
push bp
mov si,0 ;指向字符串数据缓冲区
mov bx,95 ;指向年收入
mov di,179 ;指向员工数
mov dx,054Bh ;行号及列号
mov cx,21
Average_start: push cx
push dx
mov ax,ds:[bx] ;获取年收入
mov dx,ds:[bx+2]
mov cx,ds:[di] ;获取员工数
call divdw ;计算均值
call dtoc ;转为字符串
pop dx
mov cl,04h ;数据显示属性
call putchars ;显示数据
inc dh ;行号加一
add bx,4 ;指向下一个收入数据
add di,2 ;指向下一个员工数据
pop cx
loop Average_start
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;-----------------------------------------------------------------
;函数功能:排版并显示员工数
;函数参数:无
;函数返回:无
show_people:
push ax
push bx
push cx
push dx
push si
push bp
sub sp,1
mov bp,sp
mov byte ptr ss:[bp],5;初始化开始显示行号
mov bx,179;指向员工数据开始偏移量处
mov cx,21 ;
people_start: push cx
mov ax,[bx] ;获取数据
mov dx,0
mov si,0 ;指向字符串数据缓冲区
call dtoc ;数据转换
mov dh,ss:[bp];数据显示行号
mov dl,50 ;数据列号
mov cl,04h ;数据显示属性
call putchars ;显示数据
push ax
mov al,ss:[bp] ;行号加一
inc al
mov ss:[bp],al
pop ax
add bx,2 ;指向下一个数据
pop cx
loop people_start
add sp,1
pop bp
pop si
pop dx
pop cx
pop bx
pop ax
ret
;-------------------------------------------------------------------
;函数功能:排版并显示年收入
;函数参数:无
;函数返回:无
show_summ:
push ax
push bx
push cx
push dx
push si
push bp
sub sp,1
mov bp,sp
mov byte ptr ss:[bp],5;初始化开始显示行号
mov bx,95;指向收入数据开始偏移量处
mov cx,21 ;
summ_start: push cx
mov ax,[bx] ;获取数据低16位
mov dx,[bx+2];获取数据高16位
mov si,0 ;指向字符串数据缓冲区
call dtoc ;数据转换
mov dh,ss:[bp];数据显示行号
mov dl,25 ;数据列号
mov cl,04h ;数据显示属性
call putchars ;显示数据
push ax
mov al,ss:[bp] ;行号加一
inc al
mov ss:[bp],al
pop ax
add bx,4 ;指向下一个数据
pop cx
loop summ_start
add sp,1
pop bp
pop si
pop dx
pop cx
pop bx
pop ax
ret
;-------------------------------------------------------------------
;函数功能:清屏
;函数参数:无
;函数返回:无
clear_asm: push bx
push cx
push ds
push ax
mov ax,0b800h
mov ds,ax
xor bx,bx
mov cx,2000
clear_start:mov word ptr [bx],0
add bx,2
loop clear_start
pop ax
pop ds
pop cx
pop bx
ret
;--------------------------------------------------------------------
;函数功能:排版年份并显示
;函数参数:无
;函数返回:无
show_year: push dx
push ax
push cx
push di
push si
push bp
sub sp,3
mov bp,3
mov word ptr ss:[bp],11 ;年份开始偏移量
mov byte ptr ss:[bp+2],5 ;显示开始行号
mov cx,21 ;显示年份
year_start: push cx ;保存循环次数
mov si,0 ;数据copy开始偏移量
mov di,ss:[bp] ;原数据地址
mov ax,4 ;copy数量
call strings_copy;字符串拷贝
mov dh,ss:[bp+2];数据显示行号
mov dl,0 ;数据列号
mov cl,04h ;数据显示属性
call putchars ;显示数据
push ax
mov ax,ss:[bp] ;获取年份开始偏移量
add ax,4 ;指向下一年
mov ss:[bp],ax
mov al,ss:[bp+2];获取显示开始行号
inc al
mov ss:[bp+2],al;指向下一行
pop ax
pop cx
loop year_start
add sp,3
pop bp
pop si
pop di
pop cx
pop ax
pop dx
ret
;-----------------------------------------------------------------------
;函数功能:进行字符串拷贝并在字符串尾填0
;函数参数:ax=要拷贝的数据长度 ds:di=数据开始地址 ds:si=数据拷贝后地址
;函数返回:无
strings_copy: push ax
push cx
push di
push si
mov cx,ax
copy_start: mov al,ds:[di]
mov ds:[si],al
inc di
inc si
loop copy_start
mov byte ptr ds:[si],0
pop si
pop di
pop cx
pop ax
ret
;--------------------------------------------------------------------
;函数功能:在指定位置打印指定字符串
;参数:dh行号 dl列号 cl颜色 ds:si指向字符串的首地址
;函数返回:无
putchars: push bp
push ax
push bx
push cx
push dx
push si
push di
push es
sub sp,20
mov bp,sp
mov ax,0b800h ;获取显存段地址
mov es,ax
xor ax,ax
mov al,dh ;获取行号
sub al,1
add dl,dl
mov byte ptr ss:[bp+2],dl;获取列号
mov bx,160
mul bx
add ax,ss:[bp+2] ;获取偏移地址
mov word ptr ss:[bp],ax
mov al,cl ;获取颜色
xor cx,cx
mov di,0
mov bx,0
xie_char: mov cl,ds:[si+bx];获取字符
jcxz put_return
push bx
mov bx,ss:[bp]
mov byte ptr es:[di+bx],cl ;写字符
mov byte ptr es:[di+bx+1],al ;写颜色
add di,2
pop bx
inc bx
jmp xie_char
put_return: add sp,20
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret
;---------------------------------------------------------------------
;函数功能:进行无溢出的除法运算16Bit
;函数参数:ax=dword数据的低16位 dx=dword数据高16位 cx=除数
;函数返回:dx=结果高16位 ax=结果低16位 cx=余数
divdw: push bp
push bx
sub sp,2
mov bp,sp
mov ss:[bp],ax;存放被除数低16位
mov ax,dx
xor dx,dx
div cx
mov bx,ax ;存放结果高16位
mov ax,ss:[bp]
div cx
mov cx,dx ;获取余数
mov dx,bx ;获取高16位
add sp,2
pop bx
pop bp
ret
;------------------------------------------------------------------------
;函数功能:32Bit整形数据转为字符串
;函数参数: ax数据低16位 dx数据高16位 及存放字符串的 ds:si 地址
;函数返回:无
dtoc: push ax
push bx
push cx
push dx
push si
push di
xor di,di ;用于字符串计数器 先清零
dtoc_start: mov cx,10
call divdw
mov bx,cx ;获取余数
mov cx,dx
jcxz sizo1 ;检查高16位是否为零
int_OK: add bx,30h ;转为ASCLL码
push bx ;压栈
inc di ;计算字符大小
jmp dtoc_start
sizo1: mov cx,ax
jcxz sizo2 ;检查低16位是否为零
jmp int_OK
sizo2: mov cx,bx ;检查余数是否为零
jcxz sizo3
jmp int_OK
sizo3: mov cx,di ;获取字符大小
pop_ch: pop dx
mov ds:[si],dl
inc si
loop pop_ch
mov byte ptr ds:[si],0 ;填充最后一个字符
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start
求解答 谢谢
|
最佳答案
查看完整内容
show_str:调用方法:show_str:实现过程:附件是我改完代码的输出。{:1_1:}实现代码在13楼和18楼:ton:
|