489917498 发表于 2025-10-17 13:22:40

汇编实验九

assume cs:a

d segment
db'welcome to masm'
d ends

e segment
dw 2 dup(0)
e ends

a segment
start:
mov ax,d
mov ds,ax      ;ds为字符段,si+1
mov ax,0b800h
mov es,ax      ;es为显存段,di+2
mov ax,e
mov ss,ax
mov sp,4

mov cx,15
mov bx,0
mov si,0
mov di,0
s0:
mov al,
mov byte ptr es:,al
mov byte ptr es:,0ah
add si,1
add di,2
loop s0

mov cx,15
add bx,0a0h
mov si,0
mov di,0
s1:
mov al,
mov es:,al
mov es:byte ptr ,0ah
add si,1
add di,2
loop s1


mov cx,15
add bx,140h
mov si,0
mov di,0
s2:
mov al,
mov es:,al
mov es:byte ptr ,0ah
add si,1
add di,2
loop s2

mov ax,4c00h
int 21h
a ends
end start
救命mov al,
mov es:,al
mov es:byte ptr ,0ah
这几句我逐步调试发现没有成功修改显存的值为啥啊

FishC 发表于 2025-10-17 13:24:43

你的代码中有几个问题导致没有成功修改显存。主要问题是指令不完整和显存地址计算错误。下面我逐一解释并给出修正后的代码。

问题分析:
1. 指令不完整: 在 mov al, 等指令中,缺少源操作数或目标地址,导致汇编错误或未正确执行。
2. 显存地址错误: 三个循环(s0、s1、s2)都从显存同一行(di=0)开始写入,导致后两行覆盖第一行。正确做法是每行使用不同的行偏移(第一行0,第二行0A0h,第三行140h)。

修正后的代码:

assume cs:code

data segment
    db 'welcome to masm'
data ends

stack segment
    dw 2 dup(0)
stack ends

code segment
start:
    mov ax, data
    mov ds, ax      ; ds指向数据段
    mov ax, 0b800h
    mov es, ax      ; es指向显存段
    mov ax, stack
    mov ss, ax
    mov sp, 4         ; 设置栈

    ; 第一行:显存偏移0
    mov cx, 15
    mov si, 0
    mov di, 0
s0:
    mov al,           ; 从数据段读取字符
    mov byte ptr es:, al   ; 写入显存字符字节
    mov byte ptr es:, 0ah; 写入属性字节(绿色)
    inc si                ; si+1
    add di, 2             ; di+2
    loop s0

    ; 第二行:显存偏移0A0h
    mov cx, 15
    mov si, 0
    mov di, 0A0h
s1:
    mov al,
    mov byte ptr es:, al
    mov byte ptr es:, 0ah
    inc si
    add di, 2
    loop s1

    ; 第三行:显存偏移140h
    mov cx, 15
    mov si, 0
    mov di, 140h
s2:
    mov al,
    mov byte ptr es:, al
    mov byte ptr es:, 0ah
    inc si
    add di, 2
    loop s2

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


关键修正点:
- 补全了 mov al, 为 mov al,,确保从数据段读取字符。
- 补全了显存写入指令,例如 mov byte ptr es:,al 和 mov byte ptr es:,0ah。
- 修正了行偏移:s0使用di=0,s1使用di=0A0h,s2使用di=140h,确保三行显示在不同位置。
- 使用了 inc si 替代 add si,1,使代码更简洁。

如果还有问题,请检查汇编器是否支持这些语法,并确保在调试时观察寄存器和显存值的变化。

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

FishC 发表于 2025-10-17 13:26:21

你的代码中,mov al,、mov es:,al 和 mov es:byte ptr ,0ah 这几句没有成功修改显存,主要原因有两个:

1. **地址操作数不完整**:在汇编中,mov al, 缺少源操作数(应该从数据段读取字符),而 mov es:,al 和 mov es:byte ptr ,0ah 缺少目标地址的偏移部分(应该指定显存的具体位置)。

2. **行偏移计算错误**:在第三行(s2 循环)中,add bx,140h 导致 bx 值变为 480(160 + 320),但第三行显存偏移应为 320(140h)。这会使写入位置超出预期行,可能显示在屏幕外。

修正后的关键点:
- 使用 mov al, 从数据段读取字符。
- 使用 mov es:, al 写入字符到显存低字节。
- 使用 mov byte ptr es:, 0ah 写入属性到高字节(绿色)。
- 直接设置 bx 为每行的起始偏移,而不是累加。

以下是修正后的代码片段(只显示循环部分):


assume cs:a
d segment
db 'welcome to masm'
d ends
e segment
dw 2 dup(0)
e ends
a segment
start:
mov ax, d
mov ds, ax      ; ds 指向数据段
mov ax, 0b800h
mov es, ax      ; es 指向显存段
mov ax, e
mov ss, ax
mov sp, 4

; 第一行(偏移 0)
mov cx, 15
mov bx, 0       ; 行偏移
mov si, 0
mov di, 0
s0:
mov al,             ; 从数据段读字符
mov es:, al      ; 写入字符到显存低字节
mov byte ptr es:, 0ah   ; 写入属性(绿色)
add si, 1
add di, 2
loop s0

; 第二行(偏移 160 = 0A0h)
mov cx, 15
mov bx, 160   ; 直接设置行偏移
mov si, 0
mov di, 0
s1:
mov al,
mov es:, al
mov byte ptr es:, 0ah
add si, 1
add di, 2
loop s1

; 第三行(偏移 320 = 140h)
mov cx, 15
mov bx, 320   ; 直接设置行偏移
mov si, 0
mov di, 0
s2:
mov al,
mov es:, al
mov byte ptr es:, 0ah
add si, 1
add di, 2
loop s2

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


这样修改后,字符和属性就能正确写入显存了。如果还有问题,检查调试器中的地址值是否指向 0B800h 段。

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

jackz007 发表于 2025-10-18 12:08:34

         直接运行编译好的程序,然后,观察屏幕效果,因为显存内容是屏幕的映射,你在调试程序时,屏幕内容在不断滚动更新,这就意味着显存内容也是在不断刷新中,所以,你会看到,显存中并不是你刚刚写入的数据,这很正常;反之,如果被你看到了,那才是不正常。
页: [1]
查看完整版本: 汇编实验九