17066038 发表于 2016-8-3 19:18:59

汇编语言-程序设计1-显示power idea公司的数据

哎呀,调试发现了大概不到10出错误,终于成功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个年份字符串

        dd 16,22,382,1356,2390,8000,16000,24486
        dd 50065,97479,140417,197514,345980,590287,803530,1183000
        dd 1843000,2759000,3753000,4649000,5937000
        ;--------21个公司总收入

        dw 3,7,9,13,28,38,130,220
        dw 476,778,1001,1442,2258,2793,4037,5635
        dw 8226,11542,14430,15257,17800
        ;--------21个公司雇员人数
data ends

table segment
        ;其次:定义整体内存空间,最终将所有结果转写入此段
        db 21 dup ('year summ ne ?? ')                ;每条为1年的信息
table ends

ascii segment
db 840 dup (' ')
db 8 dup (0)
ascii ends

stack segment
dw 16 dup(0)                        ;32B
stack ends

code segment
start:
        mov ax,stack
        mov ss,ax
        mov sp,32
       
        mov ax,data
        mov ds,ax
       
        mov ax,table
        mov es,ax
       
        mov bx,0
        mov si,0
        mov di,0

        ;将内存中的数据及计算出的数据写入table段中       
        mov cx,21       
totable:
        push cx                        ;非常重要

        mov ax,ds:
        mov es:,ax
        mov ax,ds:
        mov es:,ax

        mov ax,ds:
        mov es:,ax
        mov ax,ds:
        mov es:,ax

        mov ax,ds:
        mov es:,ax
       
        mov dx,es:
        mov ax,es:
        mov cx,es:
        call divdw
        mov es:,ax        ;此处丢弃了dx(商的高位),只取了ax,因原table中直给出了2B空间存储人均收入

        add bx,4
        add si,2
        add di,16
        pop cx
        loop totable                ;存储完毕跳转
       
        ;将table段中数据转换为ASCII码,存入ascii段中
        ;存储方式:年份10B_开始,收入10B_开始,雇员数10B_开始,人均收入10B_开始
        ;占用空间40*21=840B,无数据处为空格

        mov ax,table
        mov ds,ax
       
        mov ax,ascii
        mov es,ax

        mov si,0
        mov di,0

        mov cx,21
toascii:
        push cx

        ;年份传递------->>>>>>>>
        mov ax,ds:                       
        mov es:,ax
        mov ax,ds:
        mov es:,ax       
       
        ;收入传递------->>>>>>>>
        mov dx,ds:
        mov ax,ds:

        mov bx,0                ;计算余数cx的推入次数
dtocloop_sr:
        mov cx,10
        call divdw                ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
        push cx
        inc bx
        mov cx,dx
        add cx,ax
        jcxz xr_ok
        jmp short dtocloop_sr

xr_ok:        mov cx,bx
        mov bp,0
qz_sr:
        pop ax
        add ax,30h
        mov byte ptr es:,al
        inc bp
        loop qz_sr

        ;雇员数传递------->>>>>>>>
        mov dx,0
        mov ax,ds:

        mov bx,0                ;计算余数cx的推入次数
dtocloop_gys:       
        mov cx,10
        call divdw                ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
        push cx
        inc bx
        mov cx,dx
        add cx,ax
        jcxz gys_ok
        jmp dtocloop_gys       

gys_ok:        mov cx,bx
        mov bp,0
qz_gys:
        pop ax
        add ax,30h
        mov byte ptr es:,al
        inc bp
        loop qz_gys

        ;人均收入传递-------->>>>>>>>
        mov dx,0
        mov ax,ds:

        mov bx,0                ;计算余数cx的推入次数
dtocloop_rjsr:       
        mov cx,10
        call divdw                ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
        push cx
        inc bx
        mov cx,dx
        add cx,ax
        jcxz rjsr_ok
        jmp short dtocloop_rjsr       

rjsr_ok:       
        mov cx,bx
        mov bp,0
qz_rjsr:
        pop ax
        add ax,30h
        mov byte ptr es:,al
        inc bp
        loop qz_rjsr

        mov ax,0
        mov es:,ax        ;最后两字节设置00为断点
       
        add si,16
        add di,40
       
        pop cx                        ;此处无法使用loop,借用跳转命令
        dec cx
        jcxz toascii_ok
        jmp near ptr toascii       





        ;调用“显示”子程序,给定初始化值

toascii_ok:
        mov dh,3                ;给定显示的位置及颜色要求:8行3列、绿色
        mov dl,3
        mov cl,2

        mov ax,ascii
        mov ds,ax
        mov bx,0

        mov cx,21
show21:        push cx
        mov cl,2
        call show_str
        add bx,40
        inc dh
        pop cx
        loop show21

        mov ax,4c00h
        int 21h

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
show_str:
        ;参数:行=dh,列=dl,颜色值=cl,bx为设置循环使用
        ;返回值:将内存中的ASCII码内容显示出来

        ;此子程序要求给定值在相应的寄存器中:行=dh,列=dl,颜色值=cl
        ;此程序要求栈段的长度为32B

        ;要调用此子程序,须ASCII码内容在ds段中
        ;遇到字节00,停止显示

        push ds
        push es
        push si
        push di
        push ax
        push bx
        push cx
        push dx
       
        ;求目标地址
        mov ax,0b800h
        mov es,ax
        mov si,0
        mov di,0
       
        mov ax,0
        mov al,160
        dec dh                        ;从0行开始计数
        add dh,2                ;显存从第3行开始显示
        mul dh
        add di,ax

        mov ax,0
        mov al,2                ;每个要显示的字符占用2B
        dec dl                        ;列值-1,第一列转变为第0列
        mul dl                       
        add di,ax                ;求得显示的起始位置di

        mov ah,cl                ;颜色值入ah
        mov cx,0                ;清空cx的值

        ;向目标地址写入数据       
show_str_s:       
        mov cl,ds:                ;判断0,退出显示
        jcxz show_str_ok
        mov al,ds:
        mov es:,al
        mov es:,ah
        inc si
        add di,2
        jmp show_str_s

show_str_ok:       
        pop dx
        pop cx
        pop bx
        pop ax
        pop di
        pop si
        pop es
        pop ds
        ret       

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

divdw:
        ;此子程序的作用为防止被除数位32位时,商的溢出

        ;参数:dx给出32位被除数的高位,ax给出32位被除数的低位,cx除数
        ;返回值:dx给出商的的高位,ax给出商的低位,cx余数
       
        push si

        mov si,ax
        mov ax,dx
        mov dx,0       
        div cx
        push ax
        mov ax,si
        div cx
        mov cx,dx
        pop dx
       
        pop si
        ret
       

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

dtoc:
        ;参数:ax给出被除数
        ;返回值:转换结果存在ds:中,逆序存放

        ;此子程序要求给定16位被除数在寄存器ax中,除数为8位=10
        ;此程序要求栈段的长度为32B

        push ax
        push bx
        push cx
        push dx
        push si
       
        mov dx,10                ;设定除数
        mov bx,ax
dtoc_2bdiv1b_s:
        mov ah,0
        mov al,bh
        div dl
        mov ch,al
        mov al,bl
        div dl
        mov cl,al

        add ah,30h
        mov ds:,ah                ;余数写入内存ds:中
        jcxz dtoc_2bdiv1b_ok
        inc si
        mov bx,cx
        jmp dtoc_2bdiv1b_s
       
       
dtoc_2bdiv1b_ok:
        pop si
        pop dx
        pop cx
        pop bx
        pop ax
        ret       
code ends
end start

17066038 发表于 2016-8-3 19:21:45

错误:
1、再次忘记数字+30h转换为ascii码
2、loop与cx处,依然出现循环次数与子程序中的cx使用冲突忘记解决
3、...先到这吧
页: [1]
查看完整版本: 汇编语言-程序设计1-显示power idea公司的数据