鸡脖子 发表于 2024-9-8 17:01:49

实验九

assume cs:code

data segment
db 'welcome to masm!'
data ends

code segment
start:mov ax,data
          mov ds,ax

      mov ax,0B800h            ;将显存段地址传入
      mov es,ax
      
      mov bx,0
      mov bp,0
      mov cx,16
      
   s:                        ;第一行
      mov al,ds:
      mov es:,al      ;bp+1666为字属性偏移地址
      mov al,2
      mov es:,al      ;bp+1667为颜色属性偏移地址
      inc bx
      add bp,2
      loop s
      mov bx,0
      mov bp,0
      mov cx,16
s1:                        ;第二行
          mov al,ds:
      mov es:,al
      mov al,36
      mov es:,al
      inc bx
      add bp,2
      loop s1
      mov bx,0
      mov bp,0
      mov cx,16
s2:                        ;第三行
      mov al,ds:
      mov es:,al
      mov al,113
      mov es:,al
      inc bx
      add bp,2
      loop s2
      
      mov ax,4c00h
      int 21h
      
code ends
end start

FishC 发表于 2024-9-8 17:01:57

你的代码使用了MASM(微软宏汇编)语法来在屏幕上显示一些字符。你的意图是将"Welcome to MASM!"分别显示在第一、第二和第三行的不同颜色属性。但是你的代码中有一些问题,尤其是缺少对内存偏移和地址的正确处理。

以下是修正和优化过的版本:

assume cs:code

data segment
    msg db 'Welcome to MASM!'
data ends

code segment
start:
    mov ax, data
    mov ds, ax

    mov ax, 0B800h            ; 将显存段地址传入
    mov es, ax
   
    mov bx, 0               ; 初始化文字偏移
    mov cx, 16                ; 16个字符

; s段:第一行
s1:   mov al, ds:         ; 从ds段取字符
      mov es:, al         ; 写入显存位置
      mov es:, 2      ; 设置字符颜色(2,绿色)
      inc bx
      add bp, 2
      loop s1
    mov bx, 0
    add bp, 160               ; 切换到下一行

; s段:第二行
s2:   mov al, ds:         ; 从ds段取字符
      mov es:, al         ; 写入显存位置
      mov es:, 36       ; 设置字符颜色(36,为青色)
      inc bx
      add bp, 2
      loop s2
    mov bx, 0
    add bp, 160               ; 切换到下一行

; s段:第三行
s3:   mov al, ds:         ; 从ds段取字符
      mov es:, al         ; 写入显存位置
      mov es:, 113      ; 设置字符颜色(113,为白色)
      inc bx
      add bp, 2
      loop s3

    mov ax, 4c00h             ; 退出程序
    int 21h

code ends
end start

### 主要修正点:
1. 统一了段中的标签名称如 `s1`, `s2`, `s3`。
2. 修正了字符读取时未正确给出偏移地址的问题,使用了 `ds:` 来读取字符。
3. 修正并明确了颜色属性的写入位置,`es:`。
4. 在每一行处理后,增加 `add bp, 160` 来移动到下一行。
5. 套用了颜色值,便于理解。

随着这些修改,代码执行时将正确地将字符显示在显存位置,并应用不同的颜色。希望这能帮助你理解如何在汇编中操作显存和处理字符显示。如果有其他问题,请随时问我!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

jackz007 发表于 2024-9-8 20:51:03

本帖最后由 jackz007 于 2024-9-8 21:04 编辑

          给楼主一个不同的 "实验九"
assume cs:code , ds:data

data segment
    color1 equ 3
    color2 equ 36
    color3 equ 113
    db 'welcome to masm!' , 0
data ends

stack segment stack
    db 400h dup(0)
stack ends

code segment

show proc near
      push bp
      mov bp,sp
      push ax
      push cx
      push si
      push di
      push ds
      push es
      mov ax,0b800h
      mov es,ax
      mov si,               ; 需要显示字符串的偏移
      mov ds,               ; 需要显示字符串的段址
      mov cx,                ; 需要显示的起始位置(行数)
      mov ax,160
      mul cl
      mov di,ax
      mov ax,                ; 需要显示的起始位置(列数)
      shl ax,1
      add di,ax
      cld
s1:   lodsb
      or al,al
      jz s2
      stosb
      mov ax,                ; 需要显示字符的颜色
      stosb
      jmp s1
s2:   pop es
      pop ds
      pop di
      pop si
      pop cx
      pop ax
      mov sp,bp
      pop bp
      ret
show endp
main proc far
      mov ax,data
      mov ds,ax                  ; 需要显示字符串的段址
      xor si,si                  ; 需要显示字符串的偏移
      mov bx,10                  ; 需要显示的起始位置(行数)
      mov cx,33                  ; 需要显示的起始位置(列数)
      mov dx,color1                ; 需要显示字符的颜色
      mov bp,sp
      push si
      push ds
      push bx
      push cx
      push dx
      call show
      inc word ptr           ; 行数增加 1
      mov word ptr ,color2; 新的字符颜色
      call show
      inc word ptr           ; 行数增加 1
      mov word ptr ,color3; 新的字符颜色
      call show
      mov sp,bp
      mov ax,4c00h
      int 21h
main endp
code ends
end main

sunshine_8205 发表于 2024-9-8 21:11:17

{:5_106:}
页: [1]
查看完整版本: 实验九