鱼C论坛

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

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

[复制链接]
发表于 2012-11-26 16:31:32 | 显示全部楼层 |阅读模式
5鱼币
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,0a0h ;在显存数据段中b8000h每行160字节
                        dec dh ;获取前七行的偏移地址
                        mul dh 
                        add ax,3 ;得到显存的第八行第三列的偏移地址
                        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 byte ptr 0B800H[bx+DI],byte ptr [si]
                        mov byte ptr 0B800H[bx+DI].1,cl
                        inc si
                        ADD DI,2
                        jmp near ptr S
                        
                        

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

最佳答案

查看完整内容

我用EMU8086 调试的,所以,刚才那个错误没报。。。晕了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-11-26 16:31:33 | 显示全部楼层
未命名.jpg
我用EMU8086 调试的,所以,刚才那个错误没报。。。晕了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 19:04:16 | 显示全部楼层
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
楼主试下~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 19:06:37 | 显示全部楼层
整体上很好,第38行的MOV 不能同时为内存操作!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 20:08:35 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

如何修改?我还是没有看出来。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

如何修改?我还是没有看出来。
想知道小甲鱼最近在做啥?请访问 -> 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
想知道小甲鱼最近在做啥?请访问 -> 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前加了个点儿。还是不行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

把 Byte ptr 去掉。。。
3*2那没通过吗?
想知道小甲鱼最近在做啥?请访问 -> 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了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

我又重新写了一遍,这次执行成功了。不过有一点,凡是这些需要在屏幕上显示字符的代码,在WIN7下都不能显示,尽管是能成功执行。看看我第二次写的代码,自己觉的复杂了些,帮忙看看能不能优化?
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
                
        ok:        mov ax,4c00h
                int 21h
                
show_str:        push ax ;将各需要用到的寄存器入栈
                        push bx
                        push cx
                        push dx
                        push si
                        push di
                        push bp
                        
                        mov ax,0b800h ;关联显存的段地址
                        mov es,ax
                        mov ax,0
                        mov al,0a0h ;获取显存的偏移地址
                        sub dh,1
                        mul dh
                        mov dx,ax ;行的偏移地址
                        mov ah,0
                        mov al,dl
                        add ax,ax
                        add dx,ax ;题目要求的初始偏移地址
                        
                        
                        mov di,dx
                        mov ch,cl ;将字符的颜色值存入CX寄存器的高地址
                        mov bp,0 ;初始化显存地址游标
                        
                s:        
                        mov cl,byte ptr [si] ;将数据段中的字节放到CX的底地址
                        mov word ptr es:[di+bp],cx
                        jcxz short retend
                        inc si
                        add bp,2
                        loop s
                        
                        
                retend:        pop bp ;将各寄存器出栈
                                pop di
                                pop si
                                pop dx
                                pop cx
                                pop bx
                                pop ax
                                retf
                                
                code ends
end start
非常谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

刚才网站老提示网关报错,搞不定有人在破我用的无线AP。老大你发前后两句回复我没有收到。所兴自己重写了一遍。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-11-26 21:48:41 | 显示全部楼层
本帖最后由 兄弟们,冲啊 于 2012-11-26 21:49 编辑
 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 sp,16
                ;这里你既然设置了堆栈段ss那就应该设置SP
                ;不然sp是不固定的
                
                mov ax,0B800H
                mov es,ax
     ;这是附加段你没设置
     ;mov byte ptr 0B800H[bx+DI],byte ptr [si]
     ;这样是到代码段去的DS
     
     mov di,0
     ;设置di
     
                mov si,0
 
                call show_str
 
                
        ok:        mov ax,4c00h
 
                int 21h
 
                
show_str:          mov ax,0a0h ;在显存数据段中b8000h每行160字节
 
                        dec dh ;获取前七行的偏移地址
 
                        mul dh 
                        
                        mov bx,ax;将上面获得第7行的字节数保存在bx中
                        
                        ;add ax,3 ;得到显存的第八行第三列的偏移地址
       ;这句错误你没有将列数乘以2,因为有2个字节显示字符
       ;偶字节显示字符,奇字节显示颜色
       
                        mov ax,2
                        
                        mul dl 
 
                        add bx,ax;这里才是得到显存的第八行第三列的偏移地址
 
                        
                 S:     push cx ;判断最后一个字节值是否为0
 
                        mov cl,0
 
                        mov ch,byte ptr [si]
 
                        jcxz short ok
 
                        pop cx
 
                     mov al,byte ptr [si]
                     
                  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

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

呵呵,说真的,写好的时候进行编译时,不能通过,检查来检查去,怎么都没有看到这个地方这么大一个BUG。非常感谢您的提示,谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

使用道具 举报

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

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

使用道具 举报

发表于 2012-12-2 19:06:46 | 显示全部楼层
这个程序我感觉可以优化优化啊
想知道小甲鱼最近在做啥?请访问 -> 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后屏幕没有反应 没有显示字符 也不知道错了没有
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-18 08:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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