鱼C论坛

 找回密码
 立即注册
查看: 2422|回复: 19

字符串显示,子程序编写!头要爆掉

[复制链接]
发表于 2012-11-26 16:31:32 | 显示全部楼层 |阅读模式
5鱼币
  1. assume cs:code
  2. data segment
  3.         db 'Welcome to masm!',0
  4. data ends

  5. stack segment
  6.         db 16 dup (0)
  7. stack ends

  8. code segment
  9. start:        mov dh,8
  10.                 mov dl,3
  11.                 mov cl,2
  12.                 mov ax,data
  13.                 mov ds,ax
  14.                 mov ax,stack
  15.                 mov ss,ax
  16.                 mov si,0
  17.                 call show_str
  18.                
  19.         ok:        mov ax,4c00h
  20.                 int 21h
  21.                
  22. show_str:        mov ax,0a0h ;在显存数据段中b8000h每行160字节
  23.                         dec dh ;获取前七行的偏移地址
  24.                         mul dh
  25.                         add ax,3 ;得到显存的第八行第三列的偏移地址
  26.                         mov bx,ax
  27.                        
  28.                         push cx ;判断最后一个字节值是否为0
  29.                         mov cl,0
  30.                         mov ch,byte ptr [si]
  31.                         jcxz short ok
  32.                         pop cx
  33.                         MOV DI,0
  34.                         JMP S
  35.                        
  36.                 S:        mov byte ptr 0B800H[bx+DI],byte ptr [si]
  37.                         mov byte ptr 0B800H[bx+DI].1,cl
  38.                         inc si
  39.                         ADD DI,2
  40.                         jmp near ptr S
  41.                        
  42.                        

  43. code ends
  44. end start
复制代码
我捣鼓了老久,也没有捣鼓通,那位大虾帮忙指点一下,怎么改?

最佳答案

查看完整内容

我用EMU8086 调试的,所以,刚才那个错误没报。。。晕了
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2012-11-26 16:31:33 | 显示全部楼层
未命名.jpg
我用EMU8086 调试的,所以,刚才那个错误没报。。。晕了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 19:04:16 | 显示全部楼层
  1. assume cs:code
  2. data segment
  3. db 'Welcome to masm!',0
  4. data ends

  5. stack segment
  6. db 16 dup (0)
  7. stack ends

  8. code segment
  9. start: mov dh,8
  10. mov dl,3
  11. mov cl,2

  12. mov ax,data
  13. mov ds,ax
  14. mov ax,stack
  15. mov ss,ax
  16. mov si,0
  17. call show_str

  18. ok: mov ax,4c00h
  19. int 21h

  20. show_str:
  21. mov ax,0b800h
  22. mov es,ax
  23. mov ax,160 ;在显存数据段中b8000h每行160字节
  24. ;dec dh ;获取前七行的偏移地址
  25. mul dh
  26. add ax,3*2 ;得到显存的第八行第三列的偏移地址
  27. mov bx,ax

  28. push cx ;判断最后一个字节值是否为0
  29. mov cl,0
  30. mov ch,byte ptr [si]
  31. jcxz short ok
  32. pop cx
  33. MOV DI,0
  34. JMP S

  35. S:
  36. mov al,[si]
  37. push cx ;判断最后一个字节值是否为0
  38. mov cl,0
  39. mov ch,byte ptr [si]
  40. jcxz short ok
  41. pop cx
  42. mov byte ptr es:[bx+DI],al
  43. mov byte ptr es:[bx+DI]1,cl
  44. inc si
  45. ADD DI,2
  46. jmp near ptr S



  47. code ends
  48. end start
复制代码
楼主试下~~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 19:06:37 | 显示全部楼层
整体上很好,第38行的MOV 不能同时为内存操作!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 20:08:35 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 20:15:02 | 显示全部楼层
s0512 发表于 2012-11-26 19:06
整体上很好,第38行的MOV 不能同时为内存操作!

如何修改?我还是没有看出来。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 20:17:02 | 显示全部楼层
s0512 发表于 2012-11-26 19:06
整体上很好,第38行的MOV 不能同时为内存操作!

如何修改?我还是没有看出来。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 20:29:08 | 显示全部楼层
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
stack segment
db 16 dup (0)
stack ends
code segment
start: mov dh,8
mov dl,3
mov cl,2
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov si,0
call show_str
ok: mov ax,4c00h
int 21h
show_str:
mov ax,0b800h
mov es,ax
mov ax,160 ;在显存数据段中b8000h每行160字节
;dec dh ;获取前七行的偏移地址
mul dh
add ax,3*2 ;得到显存的第八行第三列的偏移地址
mov bx,ax
push cx ;判断最后一个字节值是否为0
mov cl,0
mov ch,byte ptr [si]
jcxz short ok
pop cx
MOV DI,0
JMP S
S:
mov al,[si]
push cx ;判断最后一个字节值是否为0
mov cl,0
mov ch,byte ptr [si]
jcxz short ok
pop cx ;这几句是从上前复制下来的。

mov byte ptr es:[bx+DI],al
mov byte ptr es:[bx+DI]1,cl
inc si
ADD DI,2
jmp near ptr S

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

使用道具 举报

 楼主| 发表于 2012-11-26 20:51:14 | 显示全部楼层
本帖最后由 lyoal 于 2012-11-26 20:53 编辑
s0512 发表于 2012-11-26 20:29
assume cs:code
data segment
db 'Welcome to masm!',0

哥,你测试通过了吗?为什么我的七行设置要去掉?为什么3*2?最后我还是没有编译通过。
问题出在"
mov byte ptr es:[bx+DI]1,cl
",虽然我把1前加了个点儿。还是不行
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 20:55:37 | 显示全部楼层
lyoal 发表于 2012-11-26 20:51
哥,你测试通过了吗?为什么我的七行设置要去掉?为什么3*2?最后我还是没有编译通过。
问题出在"mov by ...

把 Byte ptr 去掉。。。
3*2那没通过吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 20:58:16 | 显示全部楼层
lyoal 发表于 2012-11-26 20:51
哥,你测试通过了吗?为什么我的七行设置要去掉?为什么3*2?最后我还是没有编译通过。
问题出在"mov by ...

mov ch,byte ptr [si]
像这句就有问题,CH是8位的,所以就不需要加BYTE PTR了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 21:41:43 | 显示全部楼层
楼主您好,我只是想问一下,当您的代码执行到第36行jmp s后,如何跳出s呢?

评分

参与人数 1鱼币 +2 收起 理由
lyoal + 2

查看全部评分

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

使用道具 举报

 楼主| 发表于 2012-11-26 21:43:35 | 显示全部楼层
s0512 发表于 2012-11-26 21:01
我用EMU8086 调试的,所以,刚才那个错误没报。。。晕了

我又重新写了一遍,这次执行成功了。不过有一点,凡是这些需要在屏幕上显示字符的代码,在WIN7下都不能显示,尽管是能成功执行。看看我第二次写的代码,自己觉的复杂了些,帮忙看看能不能优化?
  1. assume cs:code
  2. data segment
  3.         db 'Welcome to masm!',0
  4. data ends

  5. code segment
  6. start:        mov dh,8
  7.                 mov dl,3
  8.                 mov cl,2
  9.                 mov ax,data
  10.                 mov ds,ax
  11.                 mov si,0
  12.                 call show_str
  13.                
  14.         ok:        mov ax,4c00h
  15.                 int 21h
  16.                
  17. show_str:        push ax ;将各需要用到的寄存器入栈
  18.                         push bx
  19.                         push cx
  20.                         push dx
  21.                         push si
  22.                         push di
  23.                         push bp
  24.                        
  25.                         mov ax,0b800h ;关联显存的段地址
  26.                         mov es,ax
  27.                         mov ax,0
  28.                         mov al,0a0h ;获取显存的偏移地址
  29.                         sub dh,1
  30.                         mul dh
  31.                         mov dx,ax ;行的偏移地址
  32.                         mov ah,0
  33.                         mov al,dl
  34.                         add ax,ax
  35.                         add dx,ax ;题目要求的初始偏移地址
  36.                        
  37.                        
  38.                         mov di,dx
  39.                         mov ch,cl ;将字符的颜色值存入CX寄存器的高地址
  40.                         mov bp,0 ;初始化显存地址游标
  41.                        
  42.                 s:       
  43.                         mov cl,byte ptr [si] ;将数据段中的字节放到CX的底地址
  44.                         mov word ptr es:[di+bp],cx
  45.                         jcxz short retend
  46.                         inc si
  47.                         add bp,2
  48.                         loop s
  49.                        
  50.                        
  51.                 retend:        pop bp ;将各寄存器出栈
  52.                                 pop di
  53.                                 pop si
  54.                                 pop dx
  55.                                 pop cx
  56.                                 pop bx
  57.                                 pop ax
  58.                                 retf
  59.                                
  60.                 code ends
  61. end start
复制代码
非常谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 21:47:23 | 显示全部楼层
s0512 发表于 2012-11-26 20:58
mov ch,byte ptr [si]
像这句就有问题,CH是8位的,所以就不需要加BYTE PTR了

刚才网站老提示网关报错,搞不定有人在破我用的无线AP。老大你发前后两句回复我没有收到。所兴自己重写了一遍。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 21:48:41 | 显示全部楼层
本帖最后由 兄弟们,冲啊 于 2012-11-26 21:49 编辑

  1. assume cs:code

  2. data segment

  3.         db 'Welcome to masm!',0

  4. data ends
  5. stack segment

  6.         db 16 dup (0)

  7. stack ends
  8. code segment

  9. start:        mov dh,8

  10.                 mov dl,3

  11.                 mov cl,2

  12.                 mov ax,data

  13.                 mov ds,ax

  14.                 mov ax,stack

  15.                 mov ss,ax
  16.                
  17.                 mov sp,16
  18.                 ;这里你既然设置了堆栈段ss那就应该设置SP
  19.                 ;不然sp是不固定的
  20.                
  21.                 mov ax,0B800H
  22.                 mov es,ax
  23.      ;这是附加段你没设置
  24.      ;mov byte ptr 0B800H[bx+DI],byte ptr [si]
  25.      ;这样是到代码段去的DS
  26.      
  27.      mov di,0
  28.      ;设置di
  29.      
  30.                 mov si,0

  31.                 call show_str

  32.                
  33.         ok:        mov ax,4c00h

  34.                 int 21h

  35.                
  36. show_str:          mov ax,0a0h ;在显存数据段中b8000h每行160字节

  37.                         dec dh ;获取前七行的偏移地址

  38.                         mul dh
  39.                         
  40.                         mov bx,ax;将上面获得第7行的字节数保存在bx中
  41.                         
  42.                         ;add ax,3 ;得到显存的第八行第三列的偏移地址
  43.        ;这句错误你没有将列数乘以2,因为有2个字节显示字符
  44.        ;偶字节显示字符,奇字节显示颜色
  45.       
  46.                         mov ax,2
  47.                         
  48.                         mul dl

  49.                         add bx,ax;这里才是得到显存的第八行第三列的偏移地址

  50.                         
  51.                  S:     push cx ;判断最后一个字节值是否为0

  52.                         mov cl,0

  53.                         mov ch,byte ptr [si]

  54.                         jcxz short ok

  55.                         pop cx

  56.                      mov al,byte ptr [si]
  57.                      
  58.                   mov byte ptr es:[bx+DI],al

  59.                         mov byte ptr es:[bx+DI+1],cl

  60.                         inc si

  61.                         ADD DI,2

  62.                         jmp near ptr S
  63.                     

  64.                                               code ends

  65. end start
复制代码

评分

参与人数 1鱼币 +2 收起 理由
lyoal + 2

查看全部评分

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

使用道具 举报

 楼主| 发表于 2012-11-26 21:48:59 | 显示全部楼层
害羞的斑马~~ 发表于 2012-11-26 21:41
楼主您好,我只是想问一下,当您的代码执行到第36行jmp s后,如何跳出s呢?

呵呵,说真的,写好的时候进行编译时,不能通过,检查来检查去,怎么都没有看到这个地方这么大一个BUG。非常感谢您的提示,谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 21:52:24 | 显示全部楼层
lyoal 发表于 2012-11-26 21:48
呵呵,说真的,写好的时候进行编译时,不能通过,检查来检查去,怎么都没有看到这个地方这么大一个BUG。非 ...

呵呵,我也是菜鸟,也在头疼这个实验。开始自己写的程序进入dos界面后编译没有任何反应,后来把程序改成小甲鱼老师给的程序后进入编译还是没有任何反应,现在都不知道是怎么回事。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 22:02:09 | 显示全部楼层

兄弟,你这一说,我发现我衰的没边儿了,这么BUG。首先我写栈,老忘设置SP。还有那个B800H这个,错以为有段寄存器的功能了。非常的失败,这下记下来。三个子程序,我这第一个就千 疮百孔了。呵呵。谢谢你们!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-12-2 19:06:46 | 显示全部楼层
这个程序我感觉可以优化优化啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-12-3 21:04:54 | 显示全部楼层
assume cs:code
data segment
  db 'welcome to masm!',0
data ends

code segment
start: mov dh,8
       mov dl,3
           mov cl,2
           mov ax,data
           mov ds,ax
           mov si,0
           call show_str
          
           mov ax,4c00h
           int 21h
          
  show_str: push bx
            push di
                        push es
            push dx
            push cx                        ;将用到的寄存器保存起来
                       
            mov al,0ah
            dec dh
                        mul dh
                        add ax,0b800h
                        mov es,ax    ;将第八行在显存中首地址付给es段寄存器
                       
                        mov al,2
                        mul dl
                        mov di,ax    ;将列的偏移地址赋值给di寄存器
                       
                        mov bx,0     ;bx指向写入显存的偏移值
                        mov al,cl
                change:
                        mov cl,byte ptr [si]
                        mov ch,0
                        jcxz ok
                        mov es:[bx+di],cl
                                mov es:[bx+di+1],al
                                add bx,2
                                inc si
                                jmp short change ;将数据段中的字符送入到显存中
                               
                        ok: pop cx
                            pop dx
                                pop es
                                pop di
                                pop bx      ;恢复子程序中的寄存器
                                ret
code ends
end start
这是我自己写的 和楼主差不多 编译都通过了 就是debug后屏幕没有反应 没有显示字符 也不知道错了没有
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-1 14:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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