鱼C论坛

 找回密码
 立即注册
查看: 3608|回复: 14

实验十 第一个子程序,大家帮忙看看代码

[复制链接]
发表于 2012-2-14 11:57:00 | 显示全部楼层 |阅读模式
1鱼币
assume cs:codesg
datasg segment
db 'welcome to masm!',0               ;定义一个字符串
datasg ends
stacksg segment                         ;定义一个空栈
dw 8 dup(0)
stacksg ends
codesg segment
start: mov dh,8h
       mov dl,3h
    mov cl,2h
    mov ax,datasg
    mov ds,ax
    mov ax,stacksg
    mov ss,ax
    mov sp,16
    mov si,0
    call show_str                  ;调用子函数
   
    mov ax,4c00h
    int 21h
show_str:push ax                    ;子函数,为了保险把所有的寄存入栈,因为我们不知道子程序会不会用到主程序里的寄存器
         push bx
   push si
   push di
   push cx
   push bp
   mov bx,0
   mov bl,cl
   mov ax,0ah
         mul dh                  ;乘以dh行,主程序提供dh
   add ax,0b800h               
   mov es,ax                     ;定义目标段地址为b800+dh*0ah
   mov bp,1                      ;计算偏移地址,第dl列的内存地址
         mul dl
s:   mov cl,[si]
   mov ch,0                       ;判断cx是否为0,为0就跳转到ok
   jcxz ok
   mov al,ds:[si]
   mov  es:[bp],al                 ;写入字符
   mov  es:[bp+1],bl                ;写入颜色
   inc si
   add bp,2
   jmp short s                       ;跳转到标号s
   
   pop di
   pop si
   pop bx
   pop ax
ok:  ret

codesg ends

end start

自己写的,经编译没有错误,但是运行后报错,不知道动了系统的什么内存。求指正。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-2-14 12:05:37 | 显示全部楼层
编译没错排除语法问题,剩下考虑逻辑问题和系统问题。系统是否Win7?是否权限不够?报错的提示是什么内容呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-2-14 13:44:26 | 显示全部楼层

C:\Documents and Settings\Administrator\桌面\cuowu.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-2-14 13:46:51 | 显示全部楼层
小甲鱼 发表于 2012-2-14 12:05
编译没错排除语法问题,剩下考虑逻辑问题和系统问题。系统是否Win7?是否权限不够?报错的提示是什么内容呢?

NTVDM CPU遇到无效指令。
cs:cdb8 IP:02b1, op: ff ff ff ff ff 选择关闭终止。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-2-15 02:12:01 | 显示全部楼层
你的子程序show_str错的太多,还是用我的这个吧!


;名称:show_str
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
;参数:dh=行号(取值范围0—24),dl=列号(取值范围0-79),cl=颜色,
;ds:si指向字符串的首地址。返还:无。
   
;应用举例:在屏幕的8行3列,用绿色显示data段中的字符串。
assume cs:codesg,ds:datasg,ss:stacksg

datasg segment
     db 'welcome to masm!',0               ;定义一个字符串
datasg ends

stacksg segment                        
      dw 8 dup(0)                           ;定义一个空栈
stacksg ends

codesg segment
start: mov dh,8h
       mov dl,3h
       mov cl,2h
       mov ax,datasg
       mov ds,ax
       mov ax,stacksg
       mov ss,ax
       mov sp,16
       mov si,0
       call show_str                  ;调用子函数
   
       mov ax,4c00h
       int 21h
show_str:                   ;显示字符串的子程序(定义开始)。
       push cx
      push si
      
      mov al,0a0h        ;每行有160个字节,转换成16进制为A0。
      dec dh             ;行号在显存中下标从0开始,所以自减1.
      mul dh           ;相当于从第(n-1)*0A0H个Byte单元开始......
      mov bx,ax          ;定位好的位置偏移地址存放在bx里(行)
      mov al,2           ;每个字符占两个字节
      mul dl         ;定位列,结果ax存放的是定位好的列的位置
      sub ax,2       ;列号在显存中下标从0开始,又因为偶字节存放字符,所以减2
      add bx,ax      ;此时bx中存放的是行与列号的偏移地址
      mov ax,0B800h  ;显存开始的地址
      mov es,ax      ;es中存放的是显存的第0页(共0--7页)的起始的段地址
      mov di,0       ;di指向显存的偏移地址,确定指向下一个要处理的字符的位置
      
      mov al,cl      ;cl是存放颜色的参数,这时候al存放颜色了,因为cl下边要用来临时存放要处理的字符
      
      mov ch,0         ;下边cx存放的是每次准备处理的字符
   s: mov cl,ds:[si]      ;ds:[si]指向“Welcome to masm!”,0
      jcxz ok             ;当cl的值为0时候,cx == 0, 则发生跳转,到OK处结束处理!
      mov es:[bx+di],cl      ;偶地址存放字符
      mov es:[bx+di+1],al     ;奇地址存放字符的颜色属性
      inc si
      add di,2         ;指向了下个字符
      jmp short s      ;无条件跳转,jcxz是离开的关键跳!
   ok:pop si
      pop cx
      ret        ;显示字符串的子程序[定义结束]
   
   
codesg ends
end start
   

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

使用道具 举报

发表于 2012-2-15 02:19:04 | 显示全部楼层
厉害。。向各位大师学习来了。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-2-24 18:30:51 | 显示全部楼层
我用5楼的调试,为为什么显示器不显示字符呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-2-24 18:32:19 | 显示全部楼层
我自己编的程序,调试的时候 有时候显示字符,有时候不显示字符,请问是为什么

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:
                                         
                
                
                         
                         mov ax,0b800h
                         mov es,ax
                         mov ax,160
                         
                         mul dh
                         push ax
                         mov al,dl
                         mov bl,2
                         mul bl
                         pop bx
                         
                         
                         add ax,bx
                       
                         mov di,ax
                         
                         s:
                           mov cl,[si]
                           mov ch,0
                           jcxz ok
                           mov bl,[si]
                           mov byte ptr es:[di],bl
                           inc di
                         
                          mov cl,2
                          
                          
                          
                           mov byte ptr es:[di],cl
                           inc di
                           inc si
                           jmp short s
                   ok: ret
         code ends
                          
        end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-2-24 20:12:51 | 显示全部楼层
本帖最后由 莫名其妙 于 2012-2-24 20:35 编辑





mov bx,0   
   mov bl,cl; 你这句话的意思应该是保存CL吧  其实 下面完全可以用(看绿字部分)  
mov ax,0ah; 这是 0a0h   
     mul dh                  ;乘以dh行,主程序提供dh
  add ax,0b800h               
   mov es,ax                     ;定义目标段地址为b800+dh*0ah
   mov bp,1                      ;计算偏移地址,第dl列的内存地址
         mul dl   ;这么乘一下 是什么意思? ax*dl? ax是多少?
   s:   mov cl,[si]
   mov ch,0                       ;判断cx是否为0,为0就跳转到ok
   jcxz ok
   mov al,ds:[si]  
   mov  es:[bp],al  
;mov cl,2  
;mov es:[xxxxxx],cl   

   mov  es:[bp+1],bl  
        ;写入颜色
   inc si
   add bp,2
   jmp short s                       ;跳转到标号s



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

使用道具 举报

 楼主| 发表于 2012-2-25 12:11:55 | 显示全部楼层
莫名其妙 发表于 2012-2-24 20:12
mov bx,0   
   mov bl,cl; 你这句话的意思应该是保存CL吧  其实 下面完全可以用(看绿字部分)  
...

绿字不能用cl ,因为cx要用于判断是否为零。只能先把cl放进另外一个寄存器。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-2-25 12:14:15 | 显示全部楼层
莫名其妙 发表于 2012-2-24 20:12
mov bx,0   
   mov bl,cl; 你这句话的意思应该是保存CL吧  其实 下面完全可以用(看绿字部分)  
...

mov bp,1
mul dl

这个指令是用于计算每行的第几列,不过,好像错了,每列2个字符才对。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-6-27 15:11:43 | 显示全部楼层
有点点看不懂……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-9-11 15:51:01 | 显示全部楼层
留个坐
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-6 09:14:38 | 显示全部楼层
厉害!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-2-15 13:50:18 | 显示全部楼层
老师们都好厉害!
这个指令是用于计算每行的第几列,不过,好像错了,每列2个字符才对。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-25 11:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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