- [smasm] assume cs:code,es:data,ss:stack,ds:table data 11/14 17:37
- [smasm] 看到论坛中有人判断ax,dx中是否为0的方法很有技巧、很好很强大,代码如下: mo 11/14 09:27
- [smasm] 原来真是我错了,那条指向是EBF6 向上跳10个字节,不是8个,还有自身的两个字节。 11/07 15:50
- [fpamc] 对的。 11/03 12:04
- [fpamc] 对的。 11/03 11:48
- [smasm] 我太粗心了!^_^ 11/01 10:38
- [fpamc] 对的 10/31 19:47
- [fpamc] 对的 10/31 19:44
- [游客] (3)返回前 cs:13fa,ds:13fd,ss:13fe code段为X则data段为X+3 10/31 18:57
- [smasm] 那少加了1??? 10/30 21:37
[2012-11-13 21:45] 课程设计一,花了好几天时间总算做完了!
data segment
;----------------------------------------------------------------------------
;数据
db "1975","1976","1977","1978","1979","1980","1981","1982","1983","1984"
db "1985","1986","1987","1988","1989","1990","1991","1992","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
;---------------------------------------------------------------------------
;人均收入储存位置
dw 21 dup (0)
data ends
;------------------------------------------------
;------------------------------------------------
;数据缓存区
table segment
db 16 dup (0)
table ends
;------------------------------------------------
;------------------------------------------------
;定义的栈
stack segment
db 32 dup (0)
stack ends
;------------------------------------------------
;-----------------------------------------------
;开始程序
code segment
start: mov ax,stack
mov ss,ax
mov sp,32
mov ax,data ;初始化ds、es、ss
mov es,ax
mov ax,table
mov ds,ax
call clr ;清屏
;------------------------------------------------
; 显示年份
mov dh,2
mov bx,0
mov cx,21
s1: push cx
;--------------------------------------------
;将年份从data段转到缓冲区 ;
mov cx,4 ;
mov si,0 ;
s2: mov al,es:[si+bx] ;
mov [si],al ;
inc si ;
loop s2 ;
mov byte ptr ds:[si],0 ;
;---------------------------------------------
mov si,0
mov dl,2
mov cl,03
call show_Str ;显示字符串
pop cx
inc dh
add bx,4
loop s1
;显示年份结束
;-----------------------------------------------------
;-----------------------------------------------------
;显示总收入数
mov dh,2
mov si,84
mov cx,21
s3:
push dx
mov ax,es:[si]
mov dx,es:[si+2]
call dtoc
pop dx
push cx
mov dl,20
mov cl,03
call show_Str
pop cx
add si,4
inc dh
loop s3
;显示总收入结束
;---------------------------------------------------
;---------------------------------------------------
; 显示雇员数
mov dh,2
mov si,168
mov cx,21
s4:
push dx
mov ax,es:[si]
mov dx,0
call dtoc
pop dx
push cx
mov dl,40
mov cl,03
call show_Str
pop cx
add si,2
inc dh
loop s4
;显示雇员数结束
;--------------------------------------------------------
;--------------------------------------------------------
;显示人均收入
mov si,84
mov bx,168
mov cx,21
s5: push cx
mov ax,es:[si]
mov dx,es:[si+2] ;计算人均收入放入数据区
mov cx,es:[bx]
call divdw
mov es:[bx+42],ax
pop cx
add si,4
add bx,2
loop s5
mov dh,2
mov si,210
mov cx,21
s6:
push dx
mov ax,es:[si] ;将收入转成字符串置于缓冲区并显示
mov dx,0
call dtoc
pop dx
push cx
mov dl,60
mov cl,03
call show_Str
pop cx
add si,2
inc dh
loop s6
;--------------------------------------------------------
mov ax,4c00H
int 21H
;程序结束
;---------------------------------------------------------
;--------------------------------------------------------
;子程序,dw数据转字符串
dtoc:
push cx
push si
push ax
mov si,0
pop ax
dtocs1: mov cx,10
call divdw
add cx,30H
mov [si],cl
mov cx,ax
jcxz dtocs2
dtocs3: inc si
jmp dtocs1
dtocs2: mov cx,dx
jcxz dtocs4
jcxz dtocs3
dtocs4: mov byte ptr [si+1],0
pop si
pop cx
call nxzfc
ret
;diwdw 功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
;参数:(ax)=dword型数据的低16位
; (dx)=dword型数据的高16位
; (cx)=word型除数
;返回:(dx)=结果的高16位,(ax)=结果的低16位
; (cx)=余数
divdw:
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
pop bx
ret
;----------------------------------------------------------------
;;/*向屏幕上写字符串
;;/*dh为屏幕行号,dl为屏幕列号
;;/*cl为字体颜色,ds:[si]指向字符串段地址,字符串以0为结束。
;;dh 取值为1~24 第25行为命令提示符,dl取值1-80。
show_str:
push ax
push bx
push dx
push cx
push es
push si
push di
mov ax,0b800H
mov es,ax
mov si,0
mov al,160
mul dh
add dl,dl
mov dh,0 ;计算写入位置,行号*160+2*列号
add ax,dx
sub ax,2
mov di,ax
mov bl,cl
show_str0: mov cx,0
mov cl, byte ptr [si]
jcxz show_str1
mov ch,bl
mov es:[di],cx
inc si
add di,2
jmp show_str0
show_str1:
pop di
pop si
pop es
pop cx
pop dx
pop bx
pop ax
ret
;;end show_str
;--------------------------------------------------------------------
;--------------------------------------------------------------------
clr: push ax ;清屏
push bx
push ds
push cx
mov ax,0b800H
mov ds,ax
mov bx,0
mov cx,3800
clr1: mov ax,0
mov [bx],al
add bx,2
loop clr1
pop cx
pop ds
pop bx
pop ax
ret
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;逆序ds:[si]指向的字符串,写回原地。
nxzfc: push ax
push cx
push si
mov si,0
mov al,0
mov cx,0
nxzfc1: mov cl,[si]
jcxz nxzfc2
push cx
inc si
inc al
jmp nxzfc1
nxzfc2: mov si,0
mov cx,ax
nxzfc3: pop ax
mov [si],al
inc si
loop nxzfc3
pop si
pop cx
pop ax
ret
code ends
end start
[ smasm 发表于 2012-11-14 09:27 ]
看到论坛中有人判断ax,dx中是否为0的方法很有技巧、很好很强大,代码如下:
mov cx,ax
or cx,dx
jcxz over
[ smasm 发表于 2012-11-14 17:37 ]
assume cs:code,es:data,ss:stack,ds:table
data segment
;----------------------------------------------------------------------------
;数据
db "1975","1976","1977","1978","1979","1980","1981","1982","1983","1984"
db "1985","1986","1987","1988","1989","1990","1991","1992","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
;---------------------------------------------------------------------------
;人均收入储存位置
dw 21 dup (0)
data ends
;------------------------------------------------
;------------------------------------------------
;数据缓存区
table segment
db 16 dup (0)
table ends
;------------------------------------------------
;------------------------------------------------
;定义的栈
stack segment
db 32 dup (0)
stack ends
;------------------------------------------------
;-----------------------------------------------
;开始程序
code segment
start: mov ax,stack
mov ss,ax
mov sp,32
call chushihua
; call clr ;清屏
; call xsnf
; call xssr
; call xsgy
call xspjsr
mov ax,4c00H
int 21H
;程序结束
;---------------------------------------------------------
;---------------------------------------------------------
;初始化
chushihua:
mov ax,data ;初始化ds、es
mov es,ax
mov ax,table
mov ds,ax
ret
;----------------------------------------------------------
;------------------------------------------------
; 显示年份
xsnf:
mov cx,21
mov si,0
mov dh,2
;--------------------------------------------
;将年份从data段转到缓冲区 ;
;
;
s1: push dx ;
mov ax,es:[si] ;
mov dx,es:[si+2] ;
mov [0],ax ;
mov [2],dx ;
mov byte ptr ds:[4],0 ;
;---------------------------------------------
pop dx
push si
mov si,0
mov dl,2
push cx
mov cx,03
call show_Str ;显示字符串
pop cx
pop si
inc dh
add si,4
loop s1
ret
;显示年份结束
;-----------------------------------------------------
;-----------------------------------------------------
;显示收入
xssr:
mov dh,2
mov si,0
mov cx,21
s3:
push dx
mov ax,es:[si+84]
mov dx,es:[si+86]
call dtoc
pop dx
push cx
push si
mov si,0
mov dl,20
mov cl,03
call show_Str
pop si
pop cx
add si,4
inc dh
loop s3
ret
;显示总收入结束
;---------------------------------------------------
;---------------------------------------------------
; 显示雇员
xsgy:
mov dh,2
mov si,168
mov cx,21
s4:
push dx
mov ax,es:[si]
mov dx,0
call dtoc
pop dx
push cx
push si
mov si,0
mov dl,40
mov cl,03
call show_Str
pop si
pop cx
add si,2
inc dh
loop s4
ret
;显示雇员数结束
;--------------------------------------------------------
;--------------------------------------------------------
;显示平均收入
xspjsr:
mov si,84
mov bx,168
mov cx,21
s5: push cx
mov ax,es:[si]
mov dx,es:[si+2] ;计算人均收入放入数据区
mov cx,es:[bx]
call divdw
mov es:[bx+42],ax
pop cx
add si,4
add bx,2
loop s5
mov dh,2
mov si,0
mov cx,21
s6:
push dx
mov ax,es:[si+210] ;将收入转成字符串置于缓冲区并显示
mov dx,0
call dtoc
pop dx
push cx
push si
mov si,0
mov dl,60
mov cl,03
call show_Str
pop si
pop cx
add si,2
inc dh
loop s6
ret
;--------------------------------------------------------
;--------------------------------------------------------
;子程序,dw数据转字符串
dtoc:
push cx
push si
push ax
mov si,0
pop ax
dtocs1: mov cx,10
call divdw
add cx,30H
mov [si],cl
mov cx,ax
or cx,dx
jcxz dtocs4
dtocs3: inc si
jmp dtocs1
dtocs4: mov byte ptr [si+1],0
pop si
pop cx
call nxzfc
ret
;diwdw 功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
;参数:(ax)=dword型数据的低16位
; (dx)=dword型数据的高16位
; (cx)=word型除数
;返回:(dx)=结果的高16位,(ax)=结果的低16位
; (cx)=余数
divdw:
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
pop bx
ret
;----------------------------------------------------------------
;;/*向屏幕上写字符串
;;/*dh为屏幕行号,dl为屏幕列号
;;/*cl为字体颜色,ds:[si]指向字符串段地址,字符串以0为结束。
;;dh 取值为1~24 第25行为命令提示符,dl取值1-80。
show_str:
push ax
push bx
push dx
push cx
push es
push di
mov ax,0b800H
mov es,ax
mov al,160
mul dh
add dl,dl
mov dh,0 ;计算写入位置,行号*160+2*列号
add ax,dx
sub ax,2
mov di,ax
mov bl,cl
show_str0: mov cx,0
mov cl, byte ptr [si]
jcxz show_str1
mov ch,bl
mov es:[di],cx
inc si
add di,2
jmp show_str0
show_str1:
pop di
pop es
pop cx
pop dx
pop bx
pop ax
ret
;;end show_str
;--------------------------------------------------------------------
;--------------------------------------------------------------------
clr: push ax ;清屏
push bx
push ds
push cx
mov ax,0b800H
mov ds,ax
mov bx,0
mov cx,3800
clr1: mov ax,0
mov [bx],al
add bx,2
loop clr1
pop cx
pop ds
pop bx
pop ax
ret
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;逆序ds:[si]指向的字符串,写回原地。
nxzfc: push ax
push cx
push si
mov si,0
mov al,0
mov cx,0
nxzfc1: mov cl,[si]
jcxz nxzfc2
push cx
inc si
inc al
jmp nxzfc1
nxzfc2: mov si,0
mov cx,ax
nxzfc3: pop ax
mov [si],al
inc si
loop nxzfc3
pop si
pop cx
pop ax
ret
code ends
end start