鱼C论坛

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

[已解决]汇编 实验10(1),大佬帮忙看看错在哪里了

[复制链接]
发表于 2019-7-27 10:22:08 | 显示全部楼层 |阅读模式

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

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

x
assume cs:code  
data segment
db 'Welcome to masm!',0
db 32 dup (0)
data ends

code segment

start: mov dh,8     ;行
       mov dl,3     ;列
           mov cl,2     ;颜色
           mov ax,data
           mov ds,ax
           mov si,0
           mov ax,0b800h
           mov es,ax
          
           call chow
          
           mov di,0
          
           mov bx,0
          
           mov cx,100
           call yanse
          
jieshu:  mov ax,4c00h
           int 21h
chow:  mov bx,16
        mov ax,0a0H
                mov [bx],dh
                mov [bx+2],dl
                mov [bx+4],cl
            mul word ptr ds:[bx]
            mov si,ax
        mov ax,[bx+2]
                mov bx,2
        mul bx
                add si,ax
                ret          ;偏移地址
yanse: push cx
        mov cl,[bx]
        mov ch,0
        jcxz jieshu               
        mov al,[bx]
        mov es:[si],al
                inc bx
                inc si
        mov al,[di+20]
        mov es:[si],al       
        inc si       
                pop cx
                loop yanse
               
               
               
               
                        
                ret
        
        
               



code ends
end start
最佳答案
2019-7-27 13:19:48
本帖最后由 jackz007 于 2019-7-27 14:44 编辑

        你的代码问题很多,我给加了注释,然后修改了有问题的地方,但是,修改量不大,尽量维持了原样,你参考吧。
  1. assume cs:code,ds:data  
  2. stack segment stack
  3.            dw 0800h dup(0)
  4. stack ends
  5. data segment
  6.     msg    db 'Welcome to masm!' , 0
  7.     buf    db 32 dup (0)
  8. data ends
  9. code segment
  10. chow proc near
  11.          mov bx,offset buf         ; bx指向数据区
  12.          mov ax,0a0H               ; ax = 160 每行显存的字节数
  13.          mov [bx],dh               ; 行号 8
  14.          mov [bx+2],dl             ; 列号 3
  15.          mov [bx+4],cl             ; 颜色 2
  16.          mul word ptr ds:[bx]      ; 0a0h * 8
  17.          mov si,ax                 ; si = 0a0h * 8
  18.          mov ax,[bx+2]             ; ax = 3            
  19.          mov bx,2                  ; bx = 2
  20.          mul bx                    ; ax = 3 * 2
  21.          add si,ax                 ; si = 0a0 * 8 + 3 * 2
  22.          ret
  23. chow endp
  24. yanse proc near
  25.          mov al,[bx]               ; 把待显示字符加载到 al 寄存器
  26.          or al,al                  ; 待显示字符是 0 ?
  27.          jz y1                     ; 如果是,那就结束显示,准备退出函数
  28.          mov es:[si],al            ; 把待显示字符储存到显存地址 es : si
  29.          inc bx                    ; 源内存地址指针增 1
  30.          inc si                    ; 显存地址增 1
  31.          mov al,[di+04h]           ; 加载待显示字符的颜色字节
  32.          mov es:[si],al            ; 把颜色字节储存到 es : si
  33.          inc si                    ; 显存地址增 1        
  34.          loop yanse
  35. y1:      ret
  36. yanse endp
  37. start proc far
  38.          mov dh,8                  ; 行
  39.          mov dl,3                  ; 列
  40.          mov cl,2                  ; 颜色
  41.          mov ax,data
  42.          mov ds,ax
  43.          mov si,0                  ; 初始化目标显存偏移为 0
  44.          mov ax,0b800h
  45.          mov es,ax
  46.          call chow                 ; 计算第 8 行第 3 列所对应的显存起始偏移,结果保存在 si 中
  47.          mov di,offset buf         ; ds : di 指向保存有行号、列号以及颜色的内存单元起始地址
  48.          mov bx,offset msg         ; ds : bx 指向待显示字符串起始地址
  49.          mov cx,100                ; 准备循环 100 次,用于显示字符串中的每一个字符
  50.          call yanse                ; 把从内存地址 ds : bx 开始的所有待显示字符传送到显存 es : si 处,完成信息显示
  51.          mov ax,4c00h
  52.          int 021h
  53. start endp
  54. code ends
  55. end start
复制代码

        如果让我来写,我会写成下面这个样子,楼主可以参考
  1. assume cs:code,ds:data
  2. stack segment stack
  3.        dw    0800h dup(00)
  4. stack ends  
  5. data segment para public 'DATA'
  6. msg    db    'Welcome to masm!' , 0
  7.        db    32 dup (0)
  8. data ends
  9. code segment para public 'CODE'
  10. main proc far
  11.            mov ax,data
  12.            mov ds,ax
  13.            mov ax,0b800h
  14.            mov es,ax
  15.            mov si,offset msg   ; si 指向待显示字符串
  16.            mov al,7            ; 第 8 行(跨过 7 个满行)
  17.            mov cl,0a0h         ; 每行显存占据 160 个字节
  18.            mul cl
  19.            add ax,04h          ; 第 3 列(跨过 2 列)
  20.            push ax
  21.            pop di              ; di = 第 8 行第 3 列在显存中的偏移
  22. m1:        lodsb               ; 从内存 ds : si 加载 1 个字节
  23.            or al,al            ; 这个字节是 0 值吗?
  24.            jz m2               ; 如果是,那就跳走
  25.            stosb               ; 把加载的字节储存到显存 es : di 处
  26.            mov al,02h          ; 颜色(绿色)
  27.            stosb               ; 把字符的颜色属性字节储存到 es : di 处
  28.            jmp m1              ; 无条件循环

  29. m2:        xor ax,ax           ; 等候用户按下任意键  
  30.            int 016h            ; 等候用户按下任意键        

  31.            mov ax,4c00h        ; 结束程序
  32.            int 021h            ; 结束程序
  33. main endp
  34. code ends
  35. end main
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-7-27 12:35:17 | 显示全部楼层
单步调试 看着也没问题, 但是一执行文件 不显示 字符串,
将他 换到 DS 寄存器 也看了下 内存单元的 值 也没问题~~实在是不懂了~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-27 13:19:48 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-7-27 14:44 编辑

        你的代码问题很多,我给加了注释,然后修改了有问题的地方,但是,修改量不大,尽量维持了原样,你参考吧。
  1. assume cs:code,ds:data  
  2. stack segment stack
  3.            dw 0800h dup(0)
  4. stack ends
  5. data segment
  6.     msg    db 'Welcome to masm!' , 0
  7.     buf    db 32 dup (0)
  8. data ends
  9. code segment
  10. chow proc near
  11.          mov bx,offset buf         ; bx指向数据区
  12.          mov ax,0a0H               ; ax = 160 每行显存的字节数
  13.          mov [bx],dh               ; 行号 8
  14.          mov [bx+2],dl             ; 列号 3
  15.          mov [bx+4],cl             ; 颜色 2
  16.          mul word ptr ds:[bx]      ; 0a0h * 8
  17.          mov si,ax                 ; si = 0a0h * 8
  18.          mov ax,[bx+2]             ; ax = 3            
  19.          mov bx,2                  ; bx = 2
  20.          mul bx                    ; ax = 3 * 2
  21.          add si,ax                 ; si = 0a0 * 8 + 3 * 2
  22.          ret
  23. chow endp
  24. yanse proc near
  25.          mov al,[bx]               ; 把待显示字符加载到 al 寄存器
  26.          or al,al                  ; 待显示字符是 0 ?
  27.          jz y1                     ; 如果是,那就结束显示,准备退出函数
  28.          mov es:[si],al            ; 把待显示字符储存到显存地址 es : si
  29.          inc bx                    ; 源内存地址指针增 1
  30.          inc si                    ; 显存地址增 1
  31.          mov al,[di+04h]           ; 加载待显示字符的颜色字节
  32.          mov es:[si],al            ; 把颜色字节储存到 es : si
  33.          inc si                    ; 显存地址增 1        
  34.          loop yanse
  35. y1:      ret
  36. yanse endp
  37. start proc far
  38.          mov dh,8                  ; 行
  39.          mov dl,3                  ; 列
  40.          mov cl,2                  ; 颜色
  41.          mov ax,data
  42.          mov ds,ax
  43.          mov si,0                  ; 初始化目标显存偏移为 0
  44.          mov ax,0b800h
  45.          mov es,ax
  46.          call chow                 ; 计算第 8 行第 3 列所对应的显存起始偏移,结果保存在 si 中
  47.          mov di,offset buf         ; ds : di 指向保存有行号、列号以及颜色的内存单元起始地址
  48.          mov bx,offset msg         ; ds : bx 指向待显示字符串起始地址
  49.          mov cx,100                ; 准备循环 100 次,用于显示字符串中的每一个字符
  50.          call yanse                ; 把从内存地址 ds : bx 开始的所有待显示字符传送到显存 es : si 处,完成信息显示
  51.          mov ax,4c00h
  52.          int 021h
  53. start endp
  54. code ends
  55. end start
复制代码

        如果让我来写,我会写成下面这个样子,楼主可以参考
  1. assume cs:code,ds:data
  2. stack segment stack
  3.        dw    0800h dup(00)
  4. stack ends  
  5. data segment para public 'DATA'
  6. msg    db    'Welcome to masm!' , 0
  7.        db    32 dup (0)
  8. data ends
  9. code segment para public 'CODE'
  10. main proc far
  11.            mov ax,data
  12.            mov ds,ax
  13.            mov ax,0b800h
  14.            mov es,ax
  15.            mov si,offset msg   ; si 指向待显示字符串
  16.            mov al,7            ; 第 8 行(跨过 7 个满行)
  17.            mov cl,0a0h         ; 每行显存占据 160 个字节
  18.            mul cl
  19.            add ax,04h          ; 第 3 列(跨过 2 列)
  20.            push ax
  21.            pop di              ; di = 第 8 行第 3 列在显存中的偏移
  22. m1:        lodsb               ; 从内存 ds : si 加载 1 个字节
  23.            or al,al            ; 这个字节是 0 值吗?
  24.            jz m2               ; 如果是,那就跳走
  25.            stosb               ; 把加载的字节储存到显存 es : di 处
  26.            mov al,02h          ; 颜色(绿色)
  27.            stosb               ; 把字符的颜色属性字节储存到 es : di 处
  28.            jmp m1              ; 无条件循环

  29. m2:        xor ax,ax           ; 等候用户按下任意键  
  30.            int 016h            ; 等候用户按下任意键        

  31.            mov ax,4c00h        ; 结束程序
  32.            int 021h            ; 结束程序
  33. main endp
  34. code ends
  35. end main
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-7-27 14:59:21 | 显示全部楼层
jackz007 发表于 2019-7-27 13:19
你的代码问题很多,我给加了注释,然后修改了有问题的地方,但是,修改量不大,尽量维持了原样,你 ...

十分感谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 00:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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