一世芳华 发表于 2012-2-14 11:57:00

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

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,
   mov ch,0                     ;判断cx是否为0,为0就跳转到ok
   jcxz ok
   mov al,ds:
   moves:,al               ;写入字符
   moves:,bl                ;写入颜色
   inc si
   add bp,2
   jmp short s                     ;跳转到标号s
   
   pop di
   pop si
   pop bx
   pop ax
ok:ret

codesg ends

end start

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


小甲鱼 发表于 2012-2-14 12:05:37

编译没错排除语法问题,剩下考虑逻辑问题和系统问题。系统是否Win7?是否权限不够?报错的提示是什么内容呢?

一世芳华 发表于 2012-2-14 13:44:26

小甲鱼 发表于 2012-2-14 12:05 static/image/common/back.gif
编译没错排除语法问题,剩下考虑逻辑问题和系统问题。系统是否Win7?是否权限不够?报错的提示是什么内容呢?

C:\Documents and Settings\Administrator\桌面\cuowu.jpg

一世芳华 发表于 2012-2-14 13:46:51

小甲鱼 发表于 2012-2-14 12:05 static/image/common/back.gif
编译没错排除语法问题,剩下考虑逻辑问题和系统问题。系统是否Win7?是否权限不够?报错的提示是什么内容呢?

NTVDM CPU遇到无效指令。
cs:cdb8 IP:02b1, op: ff ff ff ff ff 选择关闭终止。

没个正样 发表于 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:      ;ds:指向“Welcome to masm!”,0
      jcxz ok             ;当cl的值为0时候,cx == 0, 则发生跳转,到OK处结束处理!
      mov es:,cl      ;偶地址存放字符
      mov es:,al   ;奇地址存放字符的颜色属性
      inc si
      add di,2         ;指向了下个字符
      jmp short s      ;无条件跳转,jcxz是离开的关键跳!
   ok:pop si
      pop cx
      ret      ;显示字符串的子程序[定义结束]
   
   
codesg ends
end start
   

┅☆伈随风飞 发表于 2012-2-15 02:19:04

厉害。。向各位大师学习来了。。

付笑 发表于 2012-2-24 18:30:51

我用5楼的调试,为为什么显示器不显示字符呢

付笑 发表于 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,
                           mov ch,0
                           jcxz ok
                           mov bl,
                           mov byte ptr es:,bl
                           inc di
                       
                          mov cl,2
                          
                          
                          
                           mov byte ptr es:,cl
                           inc di
                           inc si
                           jmp short s
                   ok: ret
       code ends
                          
        end start

莫名其妙 发表于 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,
   mov ch,0                     ;判断cx是否为0,为0就跳转到ok
   jcxz ok
   mov al,ds:
   moves:,al
;mov cl,2
;mov es:,cl   

   moves:,bl
      ;写入颜色
   inc si
   add bp,2
   jmp short s                     ;跳转到标号s



一世芳华 发表于 2012-2-25 12:11:55

莫名其妙 发表于 2012-2-24 20:12 static/image/common/back.gif
mov bx,0   
   mov bl,cl; 你这句话的意思应该是保存CL吧其实 下面完全可以用(看绿字部分)
...

绿字不能用cl ,因为cx要用于判断是否为零。只能先把cl放进另外一个寄存器。

一世芳华 发表于 2012-2-25 12:14:15

莫名其妙 发表于 2012-2-24 20:12 static/image/common/back.gif
mov bx,0   
   mov bl,cl; 你这句话的意思应该是保存CL吧其实 下面完全可以用(看绿字部分)
...

mov bp,1
mul dl

这个指令是用于计算每行的第几列,不过,好像错了,每列2个字符才对。

黄种人 发表于 2014-6-27 15:11:43

有点点看不懂……

immortalfaith 发表于 2016-9-11 15:51:01

留个坐

独步凌波 发表于 2016-11-6 09:14:38

厉害!!!

e马先森 发表于 2017-2-15 13:50:18

老师们都好厉害!
这个指令是用于计算每行的第几列,不过,好像错了,每列2个字符才对。
页: [1]
查看完整版本: 实验十 第一个子程序,大家帮忙看看代码