assume cs:code
data segment
DB '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982'
DB '1983', '1984', '1985', '1986', '1987', '1988', '1989', '1990'
DB '1991', '1992', '1993', '1994', '1995'
;以上是表示21年的21个字符串
;偏移地址是0-53h 十进制是84-1
;每次要+4 用BX来作为寻址reg
DD 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
DD 345980, 590827, 803530, 118300, 184300, 2759000, 3753000, 4649000, 5937000
;以上是表示21年公司总收入的21个dword型数据
;偏移地址从54h-a7h 十进制是84*2=168-1
;每次要+4 用BX来作为寻址reg
DW 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226
DW 11542, 14430, 15257, 17800
;以上是表示21年公司雇员人数的21个word型数据
;偏移地址从a8h-d1h 十进制是168+42=210-1
;每次要+2 用SI来作为寻址reg
data ends
Temp segment
db 8 dup(0) ;因为最长的数据5937000是7个字符串然后追加一个字节'00'也就是8个
Temp ends
code segment
start: mov ax,data
mov es,ax
mov ax,temp
mov ds,ax
mov cx,21
mov dh,3 ;初始化显存行号
s:
;---------------------------------------年份----------------------------------------------------
yeah: push cx ;循环数入栈
push es:[bx+0]
push es:[bx+2]
pop [di+2]
pop [di+0]
mov [di+4],0 ;末位加0作为字符串结束
;行已经在DH中表示
mov dl,20 ;列
mov cl,2 ;颜色
call show_str ;赋值后调用显示
;---------------------------------------收入----------------------------------------------------
revenue:push dx ;入栈行数据
mov ax,es:[54h+bx+0]
mov dx,es:[54h+bx+2]
call dtocdd
pop dx ;出栈行数据
mov dl,31 ;列
mov cl,2 ;颜色
call show_str
;---------------------------------------雇员----------------------------------------------------
employee:
mov ax,es:[0a8h+si+0] ;这里用si作为word型寻址
call dtocdw
mov dl,41 ;列
mov cl,2 ;颜色
call show_str
;---------------------------------------人均----------------------------------------------------
per: push dx ;因为下面要进行双字节除法,所以DX(行数据)入栈
mov ax,es:[54h+bx+0]
mov dx,es:[54h+bx+2]
div word ptr es:[0a8h+si+0]
call dtocdw
pop dx
mov dl,51 ;列
mov cl,2 ;颜色
call show_str
pop cx
inc dh ;行号递增
add bx,4
add si,2
loop s
mov ax,4c00h
int 21h
;---------------------------------------显存函数开始--------------------------------------------
show_str:
push ax
push bx
push cx
push dx
push si
push di
push es ;将data段地址入栈
xor di,di
xor si,si
mov ax,0b800h
mov es,ax
mov al,80*2 ;80*2=一行字节数 160=0A0H
dec dh ;递减指令,同sub al,1 不过占用空间2字节 sub al,1是3字节
mul dh ;得到行数据
mov bx,ax ;将积传递给BX
xor dh,dh ;清除DX高位数据
add dl,dl ;获得列数据
add bx,dx ;获得偏移地址 ;将偏移地址传递给BX(因为AX不能在寻址中应用)
mov ah,cl ;将颜色值传递给ah,把cx省下作为比较用,以后第次循环少用一个栈操作
display:
;将转化后的值出栈,因为高位是0,所以只需要操作低位就可以了
mov al,[si]
mov cl,al
xor ch,ch
jcxz show_str_ok
mov es:[bx+di],ax ;AX高位是颜色,低位是颜色值
add di,2
inc si
jmp short display
show_str_ok:
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;---------------------------------------显存函数结束--------------------------------------------
;---------------------------------------双字除法函数开始--------------------------------------
dtocdd: push ax
push bx
push cx
push dx
push si
push di
push es
divdw: mov bx,ax ;bx作为低16位被除数缓存
mov ax,dx
xor dx,dx
mov cx,10 ;除数
div cx
push ax ;高16位商入栈
mov ax,bx
div cx
mov cx,dx ;余数传递给CX
pop dx ;高16商出栈
add cx,30h
push cx
inc di ;作为循环依据
mov cx,dx ;判断
add cx,ax
jcxz divdw_ok
jmp short divdw
divdw_ok:
mov cx,di
xor di,di
divdw_s:
pop ax
mov [di],al
inc di
loop divdw_s
mov byte ptr [di],0
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;---------------------------------------双字除法函数结束--------------------------------------
;---------------------------------------普通除法函数开始----------------------------------------
dtocdw: push ax
push bx
push cx
push dx
push si
push di
push es
div_Sub:mov cx,10
xor dx,dx
div cx
add dx,30h
push dx
inc di
mov cx,ax
jcxz div_Sub_Ok
jmp short div_Sub
div_Sub_Ok:
mov cx,di
xor di,di
div_Sub_Ok_s:
pop ax
mov [di],al
inc di
loop div_Sub_Ok_s
mov byte ptr [di],0
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
;---------------------------------------普通除法函数结束----------------------------------------
code ends
end start