汇编语言——程序设计1

汇编语言-程序设计1

assume cs:codesg

data segment
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984'
    db  '1985','1986','1987','1988','1989','1990','1991','1992','1993','1994'
    db  '1995'

    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980
    dd 590827,803530,1883000,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

table segment
    db 21 dup ('year summ ne ?? ')
    db 16 dup(0)
table ends

stack segment
    db 48 dup(0)
stack ends

codesg segment
start:  mov ax,stack
        mov ss,ax
        mov sp,48

        mov ax,table
        mov ds,ax

        mov ax,data
        mov es,ax

        mov bx,0
        mov di,0

        ; 循环21次
        mov cx,21

        s:  mov si,0
            push cx
            mov cx,4
            ; 向table写入年
            year:   mov al,es:[di]
                    mov [bx+0+si],al
                    inc si
                    inc di
            loop year

            ; 读取年收入
            mov ax,es:[80+di]
            mov dx,es:[82+di]

            ; 写入年收入
            mov si,0
            mov [bx+5+si],dh
            inc si
            mov [bx+5+si],dl
            inc si
            mov [bx+5+si],ah
            inc si
            mov [bx+5+si],al

            mov dx,0
            mov ax,di
            mov di,2
            div di
            mov di,ax

            ; 写入员工人数
            mov ax,es:[166+di]
            mov si,0
            mov [bx+10+si],ah
            inc si
            mov [bx+10+si],al

            mov cx,ax ;储存除数

            ;加载被除数
            mov si,0
            mov dh,[bx+5+si]
            inc si
            mov dl,[bx+5+si]
            inc si
            mov ah,[bx+5+si]
            inc si
            mov al,[bx+5+si]

            div cx

            ;写入人均收入
            mov si,0
            mov [bx+13+si],ah
            inc si
            mov [bx+13+si],al

            ; 恢复偏移地址
            add di,di

            ; 指向table的下一行
            add bx,16
            pop cx
        loop s

        ; 待调整
        mov ax,table
        mov ds,ax
        mov si,0;
        mov cx,21

    m:  push bp
        push cx;保存主循环变量
        push si

        mov bp,sp
        
        ;第一个变量为年份,直接调用show_str 进行输出
        mov dh,22
        sub dh,cl ;设置行号
        mov dl,20 ;设置列号
        mov cl,7;输出的颜色8,逐次位闪烁 背景色(R G B)高亮 前景色(R G B)

        call show_str

        ;第二个变量为年收入,需要先转数字,然后再输出
        mov dh,ds:[si+5]
        mov dl,ds:[si+6]
        mov ah,ds:[si+7]
        mov al,ds:[si+8]
        mov cx,10
        mov si,3486

        call dtoc

        mov cx, ss:[bp+2]
        mov dh,22
        sub dh,cl ;设置行号
        mov dl,40 ;设置列号
        mov cl,7;
        call show_str

        ;第三个变量 人数
        mov si, ss:[bp]
        mov dx,0
        mov ah,ds:[si+10]
        mov al,ds:[si+11]
        mov cx,10
        mov si,3486

        call dtoc

        mov cx, ss:[bp+2]
        mov dh,22
        sub dh,cl ;设置行号
        mov dl,60 ;设置列号
        mov cl,7;
        call show_str

        ;第四个变量 平均工资
        mov si, ss:[bp]
        mov dx,0
        mov ah,ds:[si+13]
        mov al,ds:[si+14]
        mov cx,10
        mov si,3486

        call dtoc

        mov cx, ss:[bp+2]
        mov dh,22
        sub dh,cl ;设置行号
        mov dl,80 ;设置列号
        mov cl,7;
        call show_str

        pop si
        add si,16; 移动到下一个

        pop cx
        
    loop m
        pop bp ; 恢复bp的值

        mov ax,4c00h
        int 21h

show_str:   push bp ;压栈保存程序执行前的寄存器数据
            push dx
            push ax
            push es
            push di
            push si
            push cx
            push bx
            
            mov bp,sp ;获取当前SP寄存器的偏移量

            mov ax,0B800H   ;获取显存的开始位置
            mov es,ax

            mov al,dh
            mov ah,0

            mov dh,0
            mov di,dx

            mov bx,160  ; dosbox 在试验机上,实测显示宽度为160
            mul bx ;获取行地址

            add di,ax ; 取得总偏移量

            mov bx,[bp+2] ; 获取颜色

        mov ch,0    ; 准备利用jcxz 进行有条件跳转
        s1: mov cl,[si]
            jcxz e1 ; 当读取出来的值为0时结束循环
            mov es:[di],cl  ;写入显存
            inc si
            inc di
            mov es:[di],bl  ;写入字体颜色
            inc di
            jmp s1
        e1: pop bx  ; 返回前恢复调用时寄存器的值
            pop cx
            pop si
            pop di
            pop es
            pop ax
            pop dx
            pop bp
        ret         ; 返回主程序

;X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
;入参 dx, H ax, L cx N
;出参 dx, H ax, L cx rem
divdw:  push bx
        push ax
        mov ax,dx
        mov dx,0
        div cx

        mov bx,ax

        pop ax
        div cx

        mov cx,dx;取得余数

        mov dx,bx;取得高16位

        pop bx

        ret

dtoc:   push bp
        push si
        push bx
        push cx

        mov bx,si

        mov bp,sp;记录下程序执行前sp的位置

       s2: call divdw
        add cl,30H
        ;mov [si],cl
        push cx
        mov cx,ax
        or cx,dx
        jcxz s3
        mov cx,10
        ;inc si
        jmp s2

       s3:  mov cx,bp
            sub cx,sp
       s4:  pop ax
            mov [si],al
            inc si
            sub cx,2
            jcxz s5
            jmp s4


       s5:  mov [si], byte ptr 0 ;末尾补零
            pop cx
            pop bx
            pop si
            pop bp
        ret

codesg ends
end start
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值