. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->直接定址表
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验16的CALL问题  [已解决] 回复[ 26次 ]   点击[ 1070次 ]  
borisyue
[帖 主]   [ 发表时间:2008-11-21 00:02 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
本人已写完实验16的代码,如下:
DATAS SEGMENT
   buff1 db "my teacher is ytt!"
   buff2 db "I am a student!" ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
   db 128 dup (0) ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    mov ax,stacks
    mov ss,ax
    mov sp,128
    
    push cs
    pop ds
    MOV AX,0
    MOV es,AX
    mov si,offset int7c
    mov di,200h
    mov cx,offset int7cend-offset int7c
    cld 
    rep movsb
    cli
    mov word ptr es:[7cH*4],200h
    mov word ptr es:[7cH*4+2],0h
    sti
    mov bx,datas
    mov ds,bx
    mov bx,0b800H
    mov es,bx
    mov si,offset buff1
    mov di,0
    mov cx,12H
s1: mov bx,[si]
    mov es:[di],bx
    mov es:[di+1],70h
    add di,2
    add si,1
    loop s1
    mov si,offset buff2
    mov di,160
    mov cx,0FH
s2: mov bx,[si]
    mov es:[di],bx
    mov es:[di+1],70h
    add di,2
    add si,1
    loop s2
    call time
    mov ah,1
    mov al,2
    int 7cH
    call time
    ;此处输入代码段代码
    MOV AH,4CH
    INT 21H
    
time:push cx
     push bx
     mov cx,3000H
nottime:mov bx,3000H
nottime1: dec bx
          jnz nottime1
          loop nottime  
     pop bx
     pop cx
     ret  
    
    int7c:jmp short set
    table:dw sub1,sub2,sub3,sub4
      set:push bx
          cmp ah,3
          ja sret
          mov bl,ah
          mov bh,0
          add bx,bx
          call word ptr table[bx]
     sret:pop bx
          iret 
          
sub1:push bx
     push cx
     push es
     mov bx,0b800h
     mov es,bx
     mov bx,0
     mov cx,2000
sub1s:mov byte ptr es:[bx],' '
      add bx,2
      loop sub1s
      pop es
      pop cx
      pop bx
      ret

sub2: push bx
      push cx
      push es
      mov bx,0b800h
      mov es,bx
      mov bx,1
      mov cx,2000
sub2s:and byte ptr es:[bx],11111000b
      or es:[bx],al
      add bx,2
      loop sub2s
      pop es
      pop cx
      pop bx
      ret
      
sub3: push bx
      push cx
      push es
      mov cl,4
      shl al,cl
      mov bx,0b800h
      mov es,bx
      mov bx,1
      mov cx,2000
sub3s:and byte ptr es:[bx],10001111b
      or es:[bx],al
      add bx,2
      loop sub3s
      pop es
      pop cx
      pop bx
      ret
      
sub4:push cx
     push si
     push di
     push es
     push ds
     mov si,0b800h
     mov es,si
     mov ds,si
     mov si,160
     mov di,0
     cld 
     mov cx,24
sub4s:push cx
     mov cx,160
     rep movsb
     pop cx
     loop sub4s
     
     mov cx,80
     mov si,0
sub4s1:mov byte ptr [160*24+si],' '
       add si,2
       loop sub4s1
       pop ds
       pop es
       pop di
       pop si
       pop cx
       ret  
int7cend:nop
   
CODES ENDS
    END START
四个子程序没有什么问题,我试过单独CALL SUB1,CALL SUB2,CALL SUB3,CALL SUB4都没什么问题。
安装INT 7CH中断程序也没什么问题。经过调试,发现到call word ptr table[bx]这一步就出问题,不能正确地定位子程序的入口。各位高手看下,哪里错了?谢谢
huibian
[第1楼]   [ 回复时间:2008-11-21 15:35 ]   [引用]   [回复]   [ top ] 
荣誉值:117
信誉值:2
注册日期:2007-09-04 10:41
装INT 7CH中断程序也没什么问题。经过调试,发现到call word ptr table[bx]这一步就出问题,不能正确地定位子程序的入口。各位高手看下,哪里错了?
------------
楼主自己是努力了,但是还不太够。这个问题是16.3直接定址表的内容的一部分,并且书上还有代码。

研究并理解了这个程序,楼主的问题自然解决了。
borisyue
[第2楼]   [ 回复时间:2008-11-21 18:19 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
我把书还给图书馆了。。今天。。。因为到期了。。麻烦高手同志们能说下吗?谢谢
borisyue
[第3楼]   [ 回复时间:2008-11-23 16:48 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
没人回答我吗?说下呀....我等这题等了好久!~
abob
[第4楼]   [ 回复时间:2008-11-23 17:02 ]   [引用]   [回复]   [ top ] 
荣誉值:169
信誉值:0
注册日期:2008-08-19 16:07
这是楼主自己写的程序吗?怎么还有两个错误。

a.ASM(39): error A2035: Operand must have size
a.ASM(48): error A2035: Operand must have size

  50574 + 450770 Bytes symbol space free

      0 Warning Errors
      2 Severe  Errors

mov es:[di+1],70h 
--------------------------
这两个错误都是相同的指令,标准的语法错误。

不知道楼主等这么久自己有什么分析的心得体会没有,还是只是等待。我觉得楼主听听一楼的意见没错。一个程序写出来只是第一步,调试出正确结果的过程才是更能提升自己能力的过程。

对于这个不太难的程序正是楼主成长的机会。

起码要说说自己分析的看法吧,要不楼主岂不越来越得不到锻炼和提升!
borisyue
[第5楼]   [ 回复时间:2008-11-24 16:07 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
这是楼主自己写的程序吗?怎么还有两个错误。

a.ASM(39): error A2035: Operand must have size
a.ASM(48): error A2035: Operand must have size

  50574 + 450770 Bytes symbol space free

      0 Warning Errors
      2 Severe  Errors

mov es:[di+1],70h 
--------------------------
这两个错误都是相同的指令,标准的语法错误。

不知道楼主等这么久自己有什么分析的心得体会没有,还是只是等待。我觉得楼主听听一楼的意见没错。一个程序写出来只是第一步,调试出正确结果的过程才是更能提升自己能力的过程。

对于这个不太难的程序正是楼主成长的机会。

起码要说说自己分析的看法吧,要不楼主岂不越来越得不到锻炼和提升!
------------------
回复:
这个程序是自己编写的一个.我在MASM编译器上能编译成功运行的.只是运行到一半会遇到NVTDM CPU遇到无效指令的窗口.我用单步调试发现到call word ptr table[bx]这一步就不能正确地调用CALL SUB1,SUB2,SUB3,SUB4
想了半天也不明白怎么回事.所以到这儿来发帖子问一下了.
至于分析心得,我再仔细看了自己的程序.感觉有一个地方不对,table:dw sub1,sub2,sub3,sub4 是不是应该改成
table dw sub1,sub2,sub3,sub4,table应该设为变量,而不是做为标号的.然后SUB1,SUB2,SUB3,SUB4是不是应该用单引号括起来做为字符串呢.我试过这样改,然后运行时还是弹出同样的问题.无语了
borisyue
[第6楼]   [ 回复时间:2008-11-27 12:47 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
没人跟帖啊..这是我的最后一个作业了...让我结业吧...
mess
[第7楼]   [ 回复时间:2008-11-27 14:56 ]   [引用]   [回复]   [ top ] 
荣誉值:337
信誉值:0
注册日期:2008-01-01 17:48
这个程序是自己编写的一个.我在MASM编译器上能编译成功运行的.+mov es:[di+1],70h  
-------------
这条指令是语言错误,是不能通过编译的。

没人跟帖啊..这是我的最后一个作业了...让我结业吧...
---------------
这个程序自己努力是能解决的,学习了为了“结业”还是学到“知识”。不会调试这样的小程序结业有什么用!
acool
[第8楼]   [ 回复时间:2008-11-27 15:54 ]   [引用]   [回复]   [ top ] 
荣誉值:49
信誉值:0
注册日期:2008-10-15 16:15
table:dw sub1,sub2,sub3,sub4 
----------------
作为子程序调用这样定义没问题,而作为通用的中断安装程序这样定义肯定是错误的,程序运行出现的无效指令也值由于这样定义而跳转到未知的位置执行指令而出现的。

如果实验要求写个普通的子程序也就没什么意思了,代码书上都有,而出现问题也是考察的一个点。

楼主不要碰到问题就喊救命,本来书上前言也要求自己独立解决问题的能力,自己独立做试验和检测,遇到问题正是我们解决问题的时候。

首先改掉程序的语言错误。--这是基本的
第二研究问什么出现这个问题,进而解决。

追求“速度”、“结业”没有任何意义,我们是来为自己“学习”地。
borisyue
[第9楼]   [ 回复时间:2008-11-27 19:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
针对七楼,mov es:[di+1],70h 这条指令在我的MASM编译器上确实能能过的,为了证实这条指令的是非,我特意查了下书发现这条指令是错的,所以我更改过来了.
针对八楼,table:dw sub1,sub2,sub3,sub4,我更改为table dw 'sub1','sub2','sub3','sub4'还是错误的.你所说的在通用的中断安装程序这样定义肯定是错误的,为什么?我不明白.我认为把INT中断程序都安装到了0:200处,然后在 call word ptr table[bx],都能找到相应的项进行call sub调用. 我真的研究过了.想了半天还是调不出来.所以不得不发到这里来.请各位大侠不吝传授.
acool
[第10楼]   [ 回复时间:2008-11-27 20:07 ]   [引用]   [回复]   [ top ] 
荣誉值:49
信誉值:0
注册日期:2008-10-15 16:15
我记得我给楼上发消息和博客留言了。
用debug跟踪程序,发现table[bx]没有确定sub1..得位置。重点解决这个问题。

针对八楼,table:dw sub1,sub2,sub3,sub4,我更改为table dw 'sub1','sub2','sub3','sub4'还是错误的
-------------------
为什么这么改啊?

实验八中提到了“相对位移”,这个问题也是一样。考虑一下为什么table[bx]段地址是cs,偏移地址却等于..
而怎么才能把他更改正确。
borisyue
[第11楼]   [ 回复时间:2008-11-27 20:35 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
持续研究的结果:
    int7c:jmp short set 
    table:dw sub1,sub2,sub3,sub4 
      set:push bx 
          cmp ah,3 
          ja sret 
          mov bl,ah 
          mov bh,0 
          add bx,bx 
          call word ptr cs:table[bx] 
     sret:pop bx 
          iret
相对于前面的代码我只是更改了一点,加上了段前缀CS,因为table不是定义在数据段,采用默认的DS肯定是不对的.table是定义在代码段,所以我加上了CS.这样想是没什么错,我运行还是弹出无效指令
call word ptr cs:table[bx] 即是获得0:table+bx的内容,在table:dw sub1,sub2,sub3,sub4中sub1,sub2,sub3,sub4都是指在段内的偏移地址,进行CALL时就把该偏移地址给了IP来达到跳转的目的.
我的语言表达不是很强,感觉想得通的却说不清.请各位高手谅解.请多多指教
borisyue
[第12楼]   [ 回复时间:2008-11-28 10:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
针对八楼,table:dw sub1,sub2,sub3,sub4,我更改为table dw 'sub1','sub2','sub3','sub4'还是错误的 
------------------- 
为什么这么改啊? 
-----------------
我想通过这样方式来获得字符串,然后把字符串提出来,达到call sub1的目的,后来想了一下根本不对的.这是错误的

call word ptr cs:table[bx]这个地方不对吗?我的想法是CS是段地址,即是0,table是标号,在这里是它的偏移地址,然后通过BX来选择sub1,sub2,sub3,sub4的偏移地址,接着在CALL时IP=sub的偏移地址达到跳转的目的.
我这分析看法对伐?
mess
[第13楼]   [ 回复时间:2008-11-28 10:40 ]   [引用]   [回复]   [ top ] 
荣誉值:337
信誉值:0
注册日期:2008-01-01 17:48
我这分析看法对伐
---------------
有了自己的分析就去debug调试一下,计算机自然告诉你是否对了。

相对于前面的代码我只是更改了一点,加上了段前缀CS,因为table不是定义在数据段,采用默认的DS肯定是不对的.table是定义在代码段,所以我加上了CS.这样想是没什么错,我运行还是弹出无效指令 
call word ptr cs:table[bx]
------------------
看看16.1,table[bx]原本默认的段地址就是cs,书上有讲解。(对于别人的思路也要思考对不对,自己理解是否正确了,而不要盲目的就去做)

考虑一下为什么table[bx]段地址是cs,偏移地址却等于.. 
--------------------
我的理解是分析table[bx]的取数据的方式,查找是否能正确读取定义的sub1等标号的地址,地址是否正确(是否改成相对地址?)
================================================
这个程序的主要问题是不能准确读取sub1 sub2..等地址,按照楼主自己的想法去调试,别人说的也只是别人的思路。要相信自己。
borisyue
[第14楼]   [ 回复时间:2008-11-28 10:40 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
int7c:jmp short int7c_set 
table dw sub1,sub2,sub3,sub4 
int7c_set:push bx 
          cmp ah,3 
          ja int7c_exit 
      mov bh,0 
      mov bl,ah 
      add bx,bx 
      call word ptr table[bx] 
int7c_exit:pop bx 
           iret
为什么人家写的是对的啊!~我拿这个来嵌套到我的程序里通过了.
而我自己的是
    int7c:jmp short set
    table dw sub1,sub2,sub3,sub4
      set:push bx
          cmp ah,3
          ja sret
          mov bl,ah
          mov bh,0
          add bx,bx
          call word ptr cs:table[bx]
     sret:pop bx
          iret 
就弹出无效指令啊!~
研究了一下,发现人家写的没有加上段前缀,而我加上了CS段前缀.table不是定义在CS代码段吗,如果不加段前缀的话,默认是DS数据段,这应该是错了啊.我自己试着把自己的段前缀拿掉,再运行还是弹出无效指令.
borisyue
[第15楼]   [ 回复时间:2008-11-28 21:08 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
为什么为什么为什么!~我都快崩溃了...我已经研究快一周了还是搞不明白.各位兄台能否给个修改的答案加上思路吗?我会拿来认真学习的.真的崩溃了...
mouselove
[第16楼]   [ 回复时间:2008-12-01 14:14 ]   [引用]   [回复]   [ top ] 
荣誉值:13
信誉值:0
注册日期:2008-03-09 16:31
table:dw sub1,sub2,sub3,sub4  
---------------------------   
如果把定义改成下面的方法,下面定位sub1 sub2 sub3 sub4应该怎么去访问呢。
这样就能确定sub1到0:200h的相对距离,进而寻址了吧
 table:dw sub1-int7c,sub2-int7c,sub3-int7c,sub4-int7c
borisyue
[第17楼]   [ 回复时间:2008-12-02 16:47 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
还是有问题。。无效指令。。。为什么需要相对距离?直接访问SUB1的偏移地址不完了嘛
borisyue
[第18楼]   [ 回复时间:2008-12-06 14:06 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
一直没人吗?囧
mouse
[第19楼]   [ 回复时间:2008-12-06 14:33 ]   [引用]   [回复]   [ top ] 
荣誉值:472
信誉值:12
注册日期:2007-10-16 15:34
还是有问题。。无效指令。。。为什么需要相对距离?直接访问SUB1的偏移地址不完了嘛
------------------
回复:问题的本质是能找到sub1的位置,也就是拷贝到0:200后sub1的位置。
至于是不是用相对距离这些问题不过是解决方法。

直接访问SUB1的偏移地址不完了嘛
---------
如果程序能正常也可以啊!是否正常计算机会告诉你。

问题的本质是能找到sub1的位置,也就是拷贝到0:200后sub1的位置。
------------
这个可以自己想想办法,找到各个地址的映射联系,进而求解。当然直接访问SUB1的偏移地址是最简单的,要是能实现当然好。

书上的程序,不仅仅是讲解了一些知识,还蕴藏了解题设计的思路等知识。要做一个程序,不论你用什么方法,首先是要实现要实现的功能,且保证正确。
qiansanshi
[第20楼]   [ 回复时间:2008-12-06 14:43 ]   [引用]   [回复]   [ top ] 
荣誉值:47
信誉值:2
注册日期:2008-08-05 09:13
为什么需要相对距离?直接访问SUB1的偏移地址不完了嘛,
mouse兄说的很对,我把跟别人解释过的再贴一下,楼主参考一下

table指的是偏移地址。如果table定义在代码段中,那么实际物理地址是cs:(table+bx)。假设table在本段代码中的偏移地址为0080h(在执行中断例程时,这个地址却变了),所以不能正确找到sub1的偏移地址。看下面解释 
 1)虽然只有一个代码段(里面又包含了一个“代码段”),假如本段代码编译后cs:ip开始为0cf0:0000。cs此时是操作系统为我们分配的段地址。而table的偏移地址0080h 
那么它是相对现在代码中的ip(即0000h)而言,table的相对地址为0080h(不知有没有这种说法,我是这样理解的。offset table-offset start),偏移地址为0080h( 相对地址 +ip) 
 2)编译连接后,用测试程序调用安装的中断例程时,cs:ip就为你事先要安装位置,即0000:0200h.此时你写的中断例程中的table定义在jmp之后,相对地址就变为2也即(offset table-offset int7),中断例程已经是一个代码段,即现在的table的偏移地址相对现在的ip而言(即变成了0200h)那么就等于0202h(ip+相对地址) 
 3)我们可以看出相对地址是不变的,而ip是可变的,即一个代码段首地址(只要cs:ip指向某一段,就可以看作代码段)并不一定都是cs:0000. 
 4)如果改一下,把7ch中断例程安装在0020:0000处(和0000:0200一样),并把安装部分放在最前面,就可以用书上的写法了,一样可以执行,但这样写不具有通用性。因为table的偏移地址就都是0002h了,因为两个ip都一样,又相对地址是不会变的,所以可以执行。
qiansanshi
[第21楼]   [ 回复时间:2008-12-06 15:35 ]   [引用]   [回复]   [ top ] 
荣誉值:47
信誉值:2
注册日期:2008-08-05 09:13
这个就是实验十六所谓的直接访问SUB1的偏移地址的方法,程序如下:


;安装地址为0020:0000用对应法(直接法)来解决,但是这种方法只适用安装的偏移地址为0000的时候
assume cs:code,ss:stack

stack segment
     db 128 dup (0)
stack ends  
   
code segment

d7cstart:    jmp near ptr set
       table dw sub0,sub1,sub2,sub3
        set: push bx 
             cmp ah,3
             ja sret
             mov bl,ah
             mov bh,0
             add bx,bx
             call word ptr table[bx]
        sret:pop bx
             iret
sub0:push bx
       push cx
       push es
       mov bx,0b800h
       mov es,bx
       mov bx,0
       mov cx,2000
     s0:mov byte ptr es:[bx],' '
        add bx,2
        loop s0
        pop es
        pop cx
        pop bx
        ret

  sub1:push bx
       push cx
       push es
       mov bx,0b800h
       mov es,bx
       mov bx,1
       mov cx,2000
     s1:and byte ptr es:[bx],11111000b
        or es:[bx],al
        add bx,2
        loop s1
        pop es
        pop cx
        pop bx
        ret
  
  sub2:push ax
       push bx
       push cx
       push es
       mov bx,0b800h
       mov es,bx
       mov cl,4
       shl al,cl
       mov bx,1
       mov cx,2000
     s2:and byte ptr es:[bx],10001111b
        or es:[bx],al
        add bx,2
        loop s2
        pop es
        pop cx
        pop bx
        pop ax
        ret

   sub3:push bx
        push cx
        push ds
        push es
        push si
        push di
        mov bx,0b800h
        mov ds,bx
        mov si,160
                
        mov es,bx
        mov di,0
        cld
                
        mov cx,24
        s3:push cx
           mov cx,160
           rep movsb
           pop cx
           loop s3
                
           mov cx,80
           mov bx,0
     s4:mov byte ptr es:[160*24+bx],' '
        add bx,2
        loop s4
                
        pop di
        pop si
        pop es
        pop ds
        pop cx
        pop bx
        ret                
  d7cend:nop
  
start:mov ax,stack
     mov ss,ax
     mov sp,128 
     mov ax,cs
     mov ds,ax
     mov si,offset d7cstart
     mov ax,0020h
     mov es,ax
     mov di,0
     mov cx,offset d7cend-offset d7cstart
     cld
     rep movsb
     mov ax,0
     mov es,ax
     mov word ptr es:[7ch*4],0
     mov word ptr es:[7ch*4+2],0020h

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

这个是安装程序,我测试过了,没问题。楼主自己研究一下吧
borisyue
[第22楼]   [ 回复时间:2008-12-10 20:55 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
谢谢各位的答解。我明白错在哪里了。然后我去修改。把中断程序放在前面了。也做了些设置更改。很像21楼的代码。但还是弹出无效指令。郁闷~~~~~~~~
qiansanshi
[第23楼]   [ 回复时间:2008-12-12 13:33 ]   [引用]   [回复]   [ top ] 
荣誉值:47
信誉值:2
注册日期:2008-08-05 09:13
今天刚看到楼主跟我发的信息,看了下你改后的代码,我想如果楼主真的去认真分析,还是很容易改过来的。帮人就帮到底吧,还是把我改后的代码贴上来,看之前建议楼主还是自己先试着修改。
程序如下:
DATAS SEGMENT 
   buff1 db "my teacher is ytt!" 
   buff2 db "I am a student!" ;此处输入数据段代码   
DATAS ENDS 

STACKS SEGMENT 
   db 128 dup (0) ;此处输入堆栈段代码 
STACKS ENDS 

CODES SEGMENT 
    ASSUME CS:CODES,DS:DATAS,SS:STACKS 
     
int7c:jmp short set 
    table dw sub1,sub2,sub3,sub4 
      set:push bx 
          cmp ah,3 
          ja sret 
          mov bl,ah 
          mov bh,0 
          add bx,bx 
          call word ptr table[bx] 
     sret:pop bx 
          iret  
           
sub1:push bx 
     push cx 
     push es 
     mov bx,0b800h 
     mov es,bx 
     mov bx,0 
     mov cx,2000 
sub1s:mov byte ptr es:[bx],' ' 
      add bx,2 
      loop sub1s 
      pop es 
      pop cx 
      pop bx 
      ret 

sub2: push bx 
      push cx 
      push es 
      mov bx,0b800h 
      mov es,bx 
      mov bx,1 
      mov cx,2000 
sub2s:and byte ptr es:[bx],11111000b 
      or es:[bx],al 
      add bx,2 
      loop sub2s 
      pop es 
      pop cx 
      pop bx 
      ret 
       
sub3: push ax 
      push bx 
      push cx 
      push es 
      mov cl,4 
      shl al,cl 
      mov bx,0b800h 
      mov es,bx 
      mov bx,1 
      mov cx,2000 
sub3s:and byte ptr es:[bx],10001111b 
      or es:[bx],al 
      add bx,2 
      loop sub3s 
      pop es 
      pop cx 
      pop bx 
      pop ax 
      ret 
       
sub4:push cx 
     push si 
     push di 
     push es 
     push ds 
     mov si,0b800h 
     mov es,si 
     mov ds,si 
     mov si,160 
     mov di,0 
     cld  
     mov cx,24 
sub4s:push cx 
     mov cx,160 
     rep movsb 
     pop cx 
     loop sub4s 
      
     mov cx,80 
     mov si,0 
sub4s1:mov byte ptr [160*24+si],' ' 
       add si,2 
       loop sub4s1 
       pop ds 
       pop es 
       pop di 
       pop si 
       pop cx 
       ret   
int7cend:nop 

START: 
    mov ax,stacks 
    mov ss,ax 
    mov sp,128 
     
    mov ax,cs 
    mov ds,ax 
    MOV AX,0020H 
    MOV es,AX 
    mov si,offset int7c 
    mov di,0H 
    mov cx,offset int7cend-offset int7c 
    cld  
    rep movsb 
    MOV AX,0
    MOV ES,AX;-----------------这两句指令楼主没有,也是产生无效指令的原因,因为没有真正修改中断向量

    cli
    mov word ptr es:[7cH*4],0h 
    mov word ptr es:[7cH*4+2],0020h 
    sti
   
    mov bx,datas 
    mov ds,bx 
    mov bx,0b800H 
    mov es,bx 
    mov si,offset buff1 
    mov di,0 
    mov bh,0
    mov cx,12H 
s1: mov bl,[si] 
    mov es:[di],bl 
    mov byte ptr es:[di+1],70h 
    add di,2 
    add si,1 
    loop s1 
    mov si,offset buff2 
    mov di,160 
    mov cx,0FH 
s2: MOV BL,[SI];-------------------每次取一个字符,最好用bl
    mov es:[di],BL 
    mov byte ptr es:[di+1],70h;----此处是常见的语法错误 
    add di,2 
    add si,1 
    loop s2 
    call time 
    mov ah,1 
    mov al,2 
    int 7cH 
    call time 
    ;此处输入代码段代码 
    MOV AH,4CH 
    INT 21H 
time:push cx 
     push bx 
     mov cx,3000H 
nottime:mov bx,3000H 
nottime1: dec bx 
          jnz nottime1 
          loop nottime   
     pop bx 
     pop cx 
     ret        

CODES ENDS 
    END START
borisyue
[第24楼]   [ 回复时间:2008-12-13 15:36 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
谢谢.一直以来麻烦你了.我学习了.
mov byte ptr es:[di+1],70h;----此处是常见的语法错误
------------------------------------------------
这个地方不明白.es:[di+1]本来就是一个字节存储器的容量,为什么还要加上byte ptr?(还是我理解错了)
答完这个就可以结帖啦!~万岁!~我给你加分分分!~嘻嘻
qiansanshi
[第25楼]   [ 回复时间:2008-12-13 18:07 ]   [引用]   [回复]   [ top ] 
荣誉值:47
信誉值:2
注册日期:2008-08-05 09:13
没什么,在汇编网上大家本来就应该相互学习
呵呵。。。感觉越简单的东西,越不好解释,就啰嗦些。
---------------------------------------------
这个地方不明白.es:[di+1]本来就是一个字节存储器的容量,为什么还要加上byte ptr?(还是我理解错了)
----------------------------------------------
这样理解是错误的。
es:(di+1)只是一个字节单元的首地址,将来以该首地址开始的内存单元存储什么类型的数据,
由将要送来的数据类型来决定。
首先我们不知道70h到底是字节型,是字型,还是双字型甚至更大,所以有如下两种方式:
mov byte ptr es:[di+1],70h;--编译后操作系统会用以es:(di+1)开始的一个字节来存放70h
mov word ptr es:[di+1],70h;--编译后操作系统会用以es:(di+1)开始的两个字节来存放70h
mov dword ptr es[di+1],70h;--编译后操作系统会用以es:(di+1)开始的四个字节来存放70h
呵呵。。如果你什么都不给的话,编译器就不知道怎么办好了,他就要报错了
另外如果编译器事先知道70h的类型,就不用加了(当然加上也不会错)所以我们可以这样:
mov al,70h   mov  es:[di+1],al;--编译器就会根据al类型来编译
mov ax,70h   mov  es:[di+1],ax;--编译器就会根据ax类型来编译
mov eax,70h  mov  es:[di+1],eax;--编译器就会根据eax类型来编译
这些如果楼主自己认真思考,去debug测试,也会很容易弄明白的。
borisyue
[第26楼]   [ 回复时间:2008-12-16 12:16 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-10-16 23:41
此贴由 贴主 于 [ 2008-12-16 12:16 ] 结贴。 结贴原因:问题已解决
得分情况: 7楼(mess):5分   10楼(acool):5分   25楼(qiansanshi):40分  
此问题已结贴!
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved