[Chapter 9] - [实验9]

思路

  • 先在data段中定义3行数据,每行32个单元,每行的前16个单元存放ASCII,每行后16个单元存放属性
  • 将data段中的内容,传递到目标缓冲区,传递的过程中,每次从data单行中前16个单元中摘出1个,后16个单元中摘出1个,构成1个组合(每个组合由1个ASCII单元和1个属性单元构成)

代码

;实验9
assume cs:code,ds:data,ss:stack
data segment
    ;要显示的第1行:黑底绿字
    db 'welcome to masm!'
    db 16 dup (00000010b)

    ;要显示的第2行:绿底红字
    db 'welcome to masm!'
    db 16 dup (00100100b)

    ;要显示的第3行:白底蓝色
    db 'welcome to masm!'
    db 16 dup (01110001b)
data ends

stack segment;存放CX计数,使内、外两层循环均可使用CX
    db 16 dup (0);最小的段区间就是16
stack ends

code segment
start:
    ;任何时候都是先实际关联
    mov ax,data
    mov ds,ax
    mov ax,0B800h
    mov es,ax;段寄存器必须借助中转

    mov ax,stack
    mov ss,ax
    mov sp,16;栈底是第15,因为栈是0~15。则超尾是第16

    ;内循环用于对32个单元进行传送
    ;外循环用于换行,共有3行需要进行同样的内循环操作
    
    mov bx,0;bx用于对显示缓冲区换行
    mov bp,0;bp用于对源区换行
    mov cx,3
    s:
        ;只要进入循环,则cx已完成减1
        ;用完cx,在进入内循环前,马上存储cx值进栈。push的动作要放在s:之内,因为只要进入s,则cx完成减1,
        ;我们需要存储的是减少1之后的cx的值,如果push放在s之外,则cx仍然为3,会陷入无限循环
        push cx
        
        mov cx,16
        mov si,0;源处ASCII区的首个单元
        mov di,11*160+64;目标处ASCII区的首个单元
        s0:
            ;以下ASCII和属性的传递,都无法采用ax的16位传递,因为需要从源处的2个区域内各提取1个,这2个数据所在单元没有相邻
            ;传递ASCII单元
            mov al,ds:[si+bp]
            mov es:[di+bx],al

            ;传递属性单元
            mov al,ds:[si+16+bp]
            mov es:[di+1+bx],al

            inc si
            add di,2
            loop s0
        add bp,32
        add bx,160
        ;
        ;内循环的次数全部执行完毕后,cx将减为0,此时退出内循环,开始下一轮外循环。也就是说,push,pop仅在外循环使用即可
        pop cx;
        loop s

        mov ax,4c00h
        int 21h
code ends
end start

运行结果如下

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值