. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->转移指令的原理
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  请问我的实验9程序哪错了,改了一个下午也没改好,显示老是不正常  [待解决] 回复[ 17次 ]   点击[ 528次 ]  
kingsgg
[帖 主]   [ 发表时间:2012-03-17 23:06 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2012-02-25 16:01
assume cs:code
data segment
      db 'welcome to masm!'
      dw 3 dup (0)
data ends
code segment
start:
      mov ax,data
      mov ds,ax
      mov ss,ax
      mov sp,16h
      mov ax,0b800h
      mov es,ax
      mov bx,0
      mov bp,0
      mov si,6e0h
      mov cx,16
    s:push cx
      mov al,ds:[bx]
      mov ah,02h
      mov es:[si+bp],ax
      add bp,2
      inc bx
      loop s
    
    s0:pop cx
      push cx
      mov bx,0
      mov bp,0
      mov al,ds:[bx]
      mov ah,24h
      mov es:[si+0a0h+bp],ax
      add bp,2
      inc bx
      loop s0

   s1:pop cx
      mov bx,0
      mov bp,0
      mov al,ds:[bx]
      mov ah,71h
      mov es:[si+140h+bp],ax
      add bp,2
      inc bx
      loop s1

      mov ax,4c00h
      int 21h
code ends
end start

编译完后运行,在屏幕中间右边只显示出'welcome'这几个字,然后就是几个小方块,第二行就只有一个绿底的小方块,第三行也是一个白底的小方块.请大大们帮下忙,我到底哪出错了,我的系统是深度技术ghostxp_sp3极速纯净版_2011.12,感激不尽!!
e56004474
[第1楼]   [ 回复时间:2012-03-18 10:57 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:1
注册日期:2008-09-04 16:35
s0:pop cx 
      push cx 
      mov bx,0 
      mov bp,0 
      mov al,ds:[bx] 
      mov ah,24h 
      mov es:[si+0a0h+bp],ax 
      add bp,2 
      inc bx 
      loop s0 


循环上有错误,debug,t进去,就发现了。
行,列,   用10进制看得明白些,比如改成 mov si,240D  ;第2行的中间.
e56004474
[第2楼]   [ 回复时间:2012-03-18 11:00 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:1
注册日期:2008-09-04 16:35
pop cx  
      push cx  
      mov bx,0  
      mov bp,0
这4条指令不能放在循环处, 第一次循环 :      add bp,2  
                                       inc bx
e56004474
[第3楼]   [ 回复时间:2012-03-18 11:03 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:1
注册日期:2008-09-04 16:35
那么 bp=2,bx=1,跳到S0,  bx,bp 又被赋值为‘0’了。

我那时候也是那样子的,后来单步进去看 各个寄存器才发现。   到时候再找找别人的,看看别人是怎么写的
kingsgg
[第4楼]   [ 回复时间:2012-03-18 11:06 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2012-02-25 16:01
今天再修改了下
assume cs:code 
data segment 
      db 'welcome to masm!' 
data ends
stack segment
      dw  8 dup (0) 
stack ends
code segment 
start: 
      mov ax,data 
      mov ds,ax 
      mov ss,stack 
      mov sp,16h 
      mov ax,0b800h 
      mov es,ax 
      mov bx,0 
      mov bp,0 
      mov si,6e0h 
      mov cx,16 
    s:push cx 
      push bx
      push bp
      mov al,ds:[bx] 
      mov ah,02h 
      mov es:[si+bp],ax 
      add bp,2 
      inc bx 
      loop s 
     
    s0:pop bp
       pop bx
       pop cx
      push cx 
      push bx
      push bp
      mov bx,0 
      mov bp,0 
      mov al,ds:[bx] 
      mov ah,24h 
      mov es:[si+0a0h+bp],ax 
      add bp,2 
      inc bx 
      loop s0 

   s1:pop bp
      pop bx
      pop cx 
      mov bx,0 
      mov bp,0 
      mov al,ds:[bx] 
      mov ah,71h 
      mov es:[si+140h+bp],ax 
      add bp,2 
      inc bx 
      loop s1 

      mov ax,4c00h 
      int 21h 
code ends 
end start 
执行后,只显示第一行,第二行和第三行只有最后"!"出来,前面的字母都没了,怎么回事啊
e56004474
[第5楼]   [ 回复时间:2012-03-18 11:28 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:1
注册日期:2008-09-04 16:35
上面说的很清楚了。
pop bp 
      pop bx 
      pop cx  
      mov bx,0  
      mov bp,0

不要放到循环里面
kingsgg
[第6楼]   [ 回复时间:2012-03-18 13:42 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2012-02-25 16:01
第二和第三循环里的MOV BX,0和MOV BP,0语句已去掉了,自制的时候不小心没删去.
lostmemory
[第7楼]   [ 回复时间:2012-03-19 09:21 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-03-06 11:51
大哥麻烦写一下注释,真看不明白
kingsgg
[第8楼]   [ 回复时间:2012-03-19 13:19 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2012-02-25 16:01
今天我用另一个方法做好了,用了26条指令,对于上面的程序我再详细说一下我的思路,上面的比较复杂,呵呵本来是想用栈来做的,但实验证明我的思路有问题,但不知是哪出错!
assume cs:code  
data segment  
      db 'welcome to masm!'  
data ends 
stack segment 
      dw  8 dup (0)         ;定义栈段,这个不用说了吧
stack ends 
code segment  
start:  
      mov ax,data  
      mov ds,ax               ;定义data段,这个也不用说了吧
      mov ss,stack  
      mov sp,16h                ;定义栈段,这个不用说了吧,指针指向栈顶
      mov ax,0b800h             ;定义显示段
      mov es,ax  
      mov bx,0  
      mov bp,0  
      mov si,7C0h                ;以上定义好需要用的寄存器
      mov cx,16     
    s:push cx                    ;因为要循环3次,将CX的值入栈保存
      push bx                     ;第一次循环后BX的值被改变,也保存BX的值
      push bp                     ;与BX同理
      mov al,ds:[bx]              ;放入DATA段的字节到AL
      mov ah,02h                   ;放入颜色到AH
      mov es:[si+bp],ax           ;将字和颜色放入显示内存
      add bp,2                    ;每次循环+2字节(显示内存)
      inc bx                       ;每次循环+1字节(DATA段)
      loop s  
      
    s0:pop bp       ;出栈,根据后入先出的原理,上一个循环是最后入的是BP,所以先出,恢复BP的值
       pop bx       ;第二个入栈,出栈也是第二个,恢复BX的值
       pop cx        ;第一个入栈,恢复CX的值,循环16次
      push cx        ;将恢复后的CX再入栈,为第三次循环做准备
      push bx        ;将恢复后的BX再入栈,思路同上
      push bp        ;将恢复后的BP入栈,思路同上
      mov al,ds:[bx]      ;将DATA段的字放入AL
      mov ah,24h          ;将颜色放入AH
      mov es:[si+0a0h+bp],ax  ;将字和颜色放入显存
      add bp,2             ;每次循环+2字节,显存段
      inc bx              ;每次循环+1字节,DATA段
      loop s0  

   s1:pop bp              ;恢复BP的值,因第二次循环是最后一个入栈,所以先出
      pop bx              ;恢复BX的值,思路同上
      pop cx               ;恢复CX的值,思路同上
      mov al,ds:[bx]     ;将DATA的字放入AL
      mov ah,71h         ;将颜色放入AH
      mov es:[si+140h+bp],ax  ;将放好的字和颜色的AX放入显存
      add bp,2              ;显存段+2字节
      inc bx                ;DATA段+1字节
      loop s1  

      mov ax,4c00h  
      int 21h  
code ends  
end start 

这个就是我的思路,但不知哪错了,只有第一行显示正常,第二、三行显示不正常,后来再写了一个简单点的,显示正常了,下楼贴出我新写的程序.
kingsgg
[第9楼]   [ 回复时间:2012-03-19 13:31 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2012-02-25 16:01
我新写的程序,显示正常了,并且代码较少
assume cs:code  
data segment  
      db 'welcome to masm!'  
data ends 
code segment  
start:  
      mov ax,data  
      mov ds,ax               ;定义data段,这个也不用说了吧
       mov ax,0b800h             ;定义显示段
       mov es,ax  
      mov bx,0  
      mov bp,0  
      mov si,7C0h                ;以上定义好需要用的寄存器
       mov cx,16     
    s: mov al,ds:[bx]              ;放入DATA段的字节到AL
      mov es:[si+bp],al           
       mov es:[si+0a0h+bp],al  
       mov es:[si+140h+bp],al 
      mov ah,02h                   ;放入颜色到AH
       mov es:[si+1+bp],ah 
      mov ah,24h          ;将第二个颜色放入AH
      mov es:[si+0a1h+bp],ah
      mov ah,71h               ;将第三个颜色放入AH
      mov es:[si+141h+bp],ah
      inc bx
      add bp,2
      loop s  

      mov ax,4c00h  
      int 21h  
code ends  
end start 

这个显示成功,并且没用到栈,只用一个循环.
e56004474
[第10楼]   [ 回复时间:2012-03-19 14:09 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:1
注册日期:2008-09-04 16:35
唉,被无视了。。
kingsgg
[第11楼]   [ 回复时间:2012-03-19 20:39 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:6
注册日期:2012-02-25 16:01
回复:[第10楼]
------------------
已经再修改好了
wzhh1986
[第12楼]   [ 回复时间:2012-05-11 20:27 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:2
注册日期:2010-12-02 13:35
要是需要显示很多种颜色的字符串,很明显,你修改后的程序不够好,不够简洁,至少没我这个简洁。我的程序如果需要的显示的颜色比较多,只需要在段中多加几个颜色上去,然后循环的个数和要显示的行数相对应改下即可。附上我写的程序。

assume cs:code,ds:data,ss:stack

data segment

  db 'welcome to masm!'      ;要显示的字符串
  db 71h,24h,2h              ;定义颜色,分别是白底蓝色、绿低红色、绿色

code segment

stack segment                ;栈段

  dw 8 dup (0)

stack ends

start:        mov ax,data
        mov ds,ax

        mov ax,0b86eh         ;0b86e为显存的第11行
        mov es,ax

        mov ax,stack
        mov ss,ax
        mov sp,16

        mov cx,3              ;以颜色的个数为外循环
        mov bp,64             ;显存的第32列,之前有32*2=64个字节
        mov bx,0

s0:        mov si,cx
        dec si                ;取颜色段中最后一个单元颜色
        mov ah,[bx+16+si]     ;ax的高位ah为颜色

        push cx               ;
        mov cx,16             ;字符串个数
        mov di,0
        mov si,0
        
s1:        mov al,[bx+si]        ;ax的低位al为要显示的字符
        mov es:[bp+di],ax     ;传到显存,以显示字符
        inc si
        add di,2
        loop s1
        add bp,160            ;显存下一行
        pop cx                ;显示完一行颜色字符串后,选取下一个颜色,再次循环显示字符串
        loop s0

        mov ax,4c00h
        int 21h

code ends

end start
wzhh1986
[第13楼]   [ 回复时间:2012-05-15 19:09 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:2
注册日期:2010-12-02 13:35
再次来看的时候发现自己手打弄错了一个地方
code segment 
stack segment               
  dw 8 dup (0) 
stack ends 
start:        mov ax,data 
这其中的code segment 应该放在stack ends 后面
wzhh1986
[第14楼]   [ 回复时间:2012-05-15 19:12 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:2
注册日期:2010-12-02 13:35
数据data段后面也少打了个 data ends
wzhh1986
[第15楼]   [ 回复时间:2012-05-15 19:18 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:2
注册日期:2010-12-02 13:35
为了书写方便,懒得频繁切换,注释符号“;”用的是中文状态下标点,需要更改为英文状态下的标点
li_ayun
[第16楼]   [ 回复时间:2015-12-18 12:37 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2015-12-15 17:17
很明显,用debug跟踪,‘w’被覆盖了,你怎么能说你运行结果是正确的!
li_ayun
[第17楼]   [ 回复时间:2015-12-18 12:46 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2015-12-15 17:17
回复:[第9楼]
------------------
很明显,用debug跟踪,‘w’被覆盖了,你怎么能说你运行结果是正确的!
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved