鱼C论坛

 找回密码
 立即注册
查看: 2881|回复: 0

[汇编作业] 实验9,根据材料编程实现及陷阱

[复制链接]
发表于 2020-11-18 18:42:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 copen55 于 2020-11-18 18:42 编辑

实现思路为:1. 三行文字,使用一个循环分三次实现。2. 同时每次循环中,需要将16个字符移动到指定位置以及带上对应的颜色,此时需要一个内层的循环实现16个字符的移动。

  1. assume cs:codesg,ds:textsg,ss:stacksg

  2. ;定义颜色
  3. ;绿色
  4. ;绿底红色
  5. ;白底蓝色
  6. colorsg segment
  7.         db 2H
  8.         db 24H
  9.         db 71H
  10. colorsg ends

  11. ;定义字符串
  12. textsg segment
  13.         db 'welcome to masm!'
  14. textsg ends

  15. stacksg segment
  16.         dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  17. stacksg ends

  18. ; 输入文字 B8000H
  19. ; 11 12 13 行分别输入
  20. ; 中间行: 160*11 = 1760 = 6E0H
  21. ; 中间位置: 160 -> 64 + 16*2 + 64
  22. ; 64=40H
  23. codesg segment
  24.         ; 缓存区重置
  25.         start:        mov ax,0B800H
  26.                         mov ds,ax
  27.                         mov bx,0

  28.                         mov cx,2000
  29.                         s:        mov ax,0
  30.                                 mov ds:[bx],ax
  31.                                 add bx,2
  32.                                 loop s

  33.         mov ax,0B86Eh                                ; 第11行开始

  34.         ; 必须是一次性刷入内容,否则缓冲区不刷新
  35.         ; mov cx,1                                        ; 一次循环
  36.         mov cx,3                                        ; 三次循环
  37.         mov bp,0                                        ; 颜色下标
  38.         s0:        push cx
  39.                 push ax
  40.                 push bp       

  41.                 mov ds,ax                                 ; 当前行的段地址
  42.                 mov bx,40H
  43.                 mov ax,textsg
  44.                 mov es,ax                                 ; 字符串段

  45.                 mov si,0                                ; 中间行 字符位置下标
  46.                 mov di,1                                ; 中间行 颜色位置下标
  47.                 mov dx,0                                ; 中间行 字符串偏移下标


  48.                 mov cx,16                                ; 所有字符循环
  49.                 s1:        push bx                         ; 保存偏移到中间位置
  50.                         mov bx,dx
  51.                         mov al,es:[bx]                ; 取出字符
  52.                         pop bx
  53.                         mov byte ptr ds:[bx+si],al          ; 写入字符

  54.                         ; 后面两行
  55.                         ; mov byte ptr ds:[bx+si+160],al
  56.                         ; mov byte ptr ds:[bx+si+320],al

  57.                         push ds                         ; 保存当前段
  58.                         mov ax,colorsg
  59.                         mov ds,ax                         ; 使用颜色段
  60.                         mov ah,ds:[bp]                   ; 颜色
  61.                         pop ds
  62.                         mov byte ptr ds:[bx+di],ah

  63.                         ; 第二个颜色
  64.                         ; push ds                         ; 保存当前段
  65.                         ; mov ax,colorsg
  66.                         ; mov ds,ax                         ; 使用颜色段
  67.                         ; mov ah,ds:[bp+1]                   ; 颜色
  68.                         ; pop ds
  69.                         ; mov byte ptr ds:[bx+di+160],ah

  70.                         ; 第三个颜色
  71.                         ; push ds                         ; 保存当前段
  72.                         ; mov ax,colorsg
  73.                         ; mov ds,ax                         ; 使用颜色段
  74.                         ; mov ah,ds:[bp+2]                   ; 颜色
  75.                         ; pop ds
  76.                         ; mov byte ptr ds:[bx+di+320],ah

  77.                        
  78.                         add si,2                        ; 增加计数
  79.                         add di,2
  80.                         inc dx
  81.                         loop s1

  82.                 pop bp
  83.                 pop ax
  84.                 pop cx

  85.                 add ax,0A0h                                 ; 移动到下一行
  86.                 inc bp
  87.                 loop s0

  88.                 mov ax,4c00h
  89.                 int 21h

  90. codesg ends

  91. end start
复制代码


但是执行效果只输出一行文字,这是缓冲区不刷新导致的,为了避免这个陷阱,需要一次性写入字符和颜色。

正常输出的一种实现思路:

  1. assume cs:codesg,ds:textsg

  2. ;定义颜色
  3. ;绿色
  4. ;绿底红色
  5. ;白底蓝色
  6. colorsg segment
  7.         db 2H
  8.         db 24H
  9.         db 71H
  10. colorsg ends

  11. ;定义字符串
  12. textsg segment
  13.         db 'welcome to masm!'
  14. textsg ends


  15. ; 输入文字 B8000H
  16. ; 11 12 13 行分别输入
  17. ; 中间行: 160*11 = 1760 = 6E0H
  18. ; 中间位置: 160 -> 64 + 16*2 + 64
  19. ; 64=40H
  20. codesg segment
  21.         ; 缓存区重置
  22.         ; 非必要的
  23.         start:        mov ax,0B800H
  24.                         mov ds,ax
  25.                         mov bx,0

  26.                         mov cx,2000
  27.                         s:        mov ax,0
  28.                                 mov ds:[bx],ax
  29.                                 add bx,2
  30.                                 loop s

  31.     mov ax,0B86Eh                                                ; 第11行开始
  32.         mov ds,ax                                                         ; 当前行的段地址
  33.         mov ax,textsg
  34.         mov es,ax                                                         ; 字符串段

  35.         mov bx,colorsg                                                ; 颜色段

  36.         mov si,0                                                        ; 中间行 字符位置下标
  37.         mov di,1                                                        ; 中间行 颜色位置下标
  38.         mov bp,0                                                        ; 中间行 字符串偏移下标
  39.         mov dx,0                                                        ; ds 中间保存寄存器


  40.         mov cx,16                                                        ; 所有字符循环
  41.         s1:        mov al,es:[bp]                                        ; 取出字符
  42.                 mov byte ptr ds:[si+64],al          ; 写入字符
  43.                 mov byte ptr ds:[si+224],al                ; 64+160 12行
  44.                 mov byte ptr ds:[si+384],al     ; 64+320 13行

  45.                 mov dx,ds                                                 ; 保存当前段
  46.                 mov ds,bx
  47.                 mov ah,ds:[0]                                           ; 颜色 1
  48.                 mov ds,dx
  49.                 mov byte ptr ds:[di+64],ah

  50.                 mov dx,ds                                                 ; 保存当前段
  51.                 mov ds,bx
  52.                 mov ah, ds:[1]                                        ; 颜色 2
  53.                 mov ds,dx
  54.                 mov byte ptr ds:[di+224],ah

  55.                 mov dx,ds                                                 ; 保存当前段
  56.                 mov ds,bx
  57.                 mov ah, ds:[2]                                        ; 颜色 3
  58.                 mov ds,dx
  59.                 mov byte ptr ds:[di+384],ah

  60.                 add si,2                        ; 增加计数
  61.                 add di,2
  62.                 inc bp
  63.                 loop s1

  64.         mov ax,4c00h
  65.         int 21h

  66. codesg ends

  67. end start
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 22:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表