鱼C论坛

 找回密码
 立即注册
查看: 64|回复: 3

汇编实验九

[复制链接]
发表于 昨天 13:22 | 显示全部楼层 |阅读模式

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

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

x
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,[si]
mov byte ptr es:[bx+di],al
mov byte ptr es:[bx+di+1],0ah
add si,1
add di,2
loop s0

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


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

mov ax,4c00h
int 21h
a ends
end start
救命mov al,[si]
mov es:[bx+di],al
mov es:byte ptr [bx+di+1],0ah
这几句我逐步调试发现没有成功修改显存的值为啥啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 13:24 | 显示全部楼层
你的代码中有几个问题导致没有成功修改显存。主要问题是指令不完整和显存地址计算错误。下面我逐一解释并给出修正后的代码。

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

修正后的代码:

  1. assume cs:code

  2. data segment
  3.     db 'welcome to masm'
  4. data ends

  5. stack segment
  6.     dw 2 dup(0)
  7. stack ends

  8. code segment
  9. start:
  10.     mov ax, data
  11.     mov ds, ax        ; ds指向数据段
  12.     mov ax, 0b800h
  13.     mov es, ax        ; es指向显存段
  14.     mov ax, stack
  15.     mov ss, ax
  16.     mov sp, 4         ; 设置栈

  17.     ; 第一行:显存偏移0
  18.     mov cx, 15
  19.     mov si, 0
  20.     mov di, 0
  21. s0:
  22.     mov al, [si]          ; 从数据段读取字符
  23.     mov byte ptr es:[di], al     ; 写入显存字符字节
  24.     mov byte ptr es:[di+1], 0ah  ; 写入属性字节(绿色)
  25.     inc si                ; si+1
  26.     add di, 2             ; di+2
  27.     loop s0

  28.     ; 第二行:显存偏移0A0h
  29.     mov cx, 15
  30.     mov si, 0
  31.     mov di, 0A0h
  32. s1:
  33.     mov al, [si]
  34.     mov byte ptr es:[di], al
  35.     mov byte ptr es:[di+1], 0ah
  36.     inc si
  37.     add di, 2
  38.     loop s1

  39.     ; 第三行:显存偏移140h
  40.     mov cx, 15
  41.     mov si, 0
  42.     mov di, 140h
  43. s2:
  44.     mov al, [si]
  45.     mov byte ptr es:[di], al
  46.     mov byte ptr es:[di+1], 0ah
  47.     inc si
  48.     add di, 2
  49.     loop s2

  50.     mov ax, 4c00h
  51.     int 21h
  52. code ends
  53. end start
复制代码


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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 13:26 | 显示全部楼层
你的代码中,mov al,mov es:,almov es:byte ptr ,0ah 这几句没有成功修改显存,主要原因有两个:

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

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

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

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


  1. assume cs:a
  2. d segment
  3.   db 'welcome to masm'
  4. d ends
  5. e segment
  6.   dw 2 dup(0)
  7. e ends
  8. a segment
  9. start:
  10.   mov ax, d
  11.   mov ds, ax      ; ds 指向数据段
  12.   mov ax, 0b800h
  13.   mov es, ax      ; es 指向显存段
  14.   mov ax, e
  15.   mov ss, ax
  16.   mov sp, 4

  17.   ; 第一行(偏移 0)
  18.   mov cx, 15
  19.   mov bx, 0       ; 行偏移
  20.   mov si, 0
  21.   mov di, 0
  22. s0:
  23.   mov al, [si]              ; 从数据段读字符
  24.   mov es:[bx+di], al        ; 写入字符到显存低字节
  25.   mov byte ptr es:[bx+di+1], 0ah   ; 写入属性(绿色)
  26.   add si, 1
  27.   add di, 2
  28.   loop s0

  29.   ; 第二行(偏移 160 = 0A0h)
  30.   mov cx, 15
  31.   mov bx, 160     ; 直接设置行偏移
  32.   mov si, 0
  33.   mov di, 0
  34. s1:
  35.   mov al, [si]
  36.   mov es:[bx+di], al
  37.   mov byte ptr es:[bx+di+1], 0ah
  38.   add si, 1
  39.   add di, 2
  40.   loop s1

  41.   ; 第三行(偏移 320 = 140h)
  42.   mov cx, 15
  43.   mov bx, 320     ; 直接设置行偏移
  44.   mov si, 0
  45.   mov di, 0
  46. s2:
  47.   mov al, [si]
  48.   mov es:[bx+di], al
  49.   mov byte ptr es:[bx+di+1], 0ah
  50.   add si, 1
  51.   add di, 2
  52.   loop s2

  53.   mov ax, 4c00h
  54.   int 21h
  55. a ends
  56. end start
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 28 秒前 | 显示全部楼层
         直接运行编译好的程序,然后,观察屏幕效果,因为显存内容是屏幕的映射,你在调试程序时,屏幕内容在不断滚动更新,这就意味着显存内容也是在不断刷新中,所以,你会看到,显存中并不是你刚刚写入的数据,这很正常;反之,如果被你看到了,那才是不正常。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-10-18 12:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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