鱼C论坛

 找回密码
 立即注册
查看: 5101|回复: 18

王爽汇编实验16

[复制链接]
发表于 2013-3-20 16:36:16 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 大西洋1912 于 2013-3-20 17:45 编辑
  1. assume cs:code
  2. code segment
  3. start:        mov ax,cs
  4.                                 mov ds,ax
  5.                                 mov si,offset setSrc  ;设置复制的起始地址
  6.                                 
  7.                                 mov ax,0
  8.                                 mov es,ax
  9.                                 mov di,200h;设置复制的目标地址
  10.                                 
  11.                                 mov cx,offset setEnd - offset setSrc ;获取复制的数据的长度
  12.                                 
  13.                                 cld
  14.                                 rep movsb
  15.                                 
  16.                                 mov word ptr es:[7ch*4],200h;注册int 7ch中断向量
  17.                                 mov word ptr es:[7ch*4+2],0
  18.                                 
  19.                                 mov ah,0;用户输入的数据
  20.                                 int 7ch
  21.                                 
  22.                                 mov ax,4c00h
  23.                                 int 21h
  24.                                 
  25. setSrc:        jmp short next
  26.                                 c        dw        sub1,sub2;定义的直接定址表
  27.                                 
  28.         next:        mov bl,ah
  29.                                 mov bh,0
  30.                                 add bl,bl
  31.                                 
  32.                                 call word ptr c[bx]                ;为什么这里不能跳转到sub1标号处执行(为什么没有获取到sub1的偏移地址)
  33.                                 
  34.                                 iret
  35.                                 
  36.         sub1:        push es    ;下面是两个子程序,分别为输出1和2
  37.                                 push di
  38.                                 push bx
  39.                                 mov bx,0b800h
  40.                                 mov es,bx
  41.                                 mov di,160*12+40*2
  42.                                 mov byte ptr es:[di],'1'
  43.                                 pop bx
  44.                                 pop di
  45.                                 pop es
  46.                                 ret

  47.         sub2:        push es
  48.                                 push di
  49.                                 push bx
  50.                                 mov bx,0b800h
  51.                                 mov es,bx
  52.                                 mov di,160*12+40*2
  53.                                 mov byte ptr es:[di],'2'
  54.                                 pop bx
  55.                                 pop di
  56.                                 pop es
  57.                                 ret
  58.         
  59. setEnd:        nop
  60.                                 
  61. code ends
  62. end start
复制代码
为什么call word ptr c[bx]没有寻找到子程序的入口偏移地址,大神,求指导

最佳答案

查看完整内容

我给个我自己打得程序你把,具体的要注意什么都有写了 具体干什么的,上面都有写,是书本的例子吧,也有一些注释什么的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-3-20 16:36:17 | 显示全部楼层
我给个我自己打得程序你把,具体的要注意什么都有写了
具体干什么的,上面都有写,是书本的例子吧,也有一些注释什么的
  1. ;编程:实现一个子程序setscreen,为显示输出提供如下功能:
  2. ;(0) 清屏。
  3. ;(1) 设置前景色。
  4. ;(2) 设置背景色。
  5. ;(3) 向上滚动一行。
  6. ;
  7. ;入口参数说明:
  8. ;(1) 用 ah 寄存器传递功能号:0 表示清屏,1表示设置前景色,2 表示设置背景色,3 表示向上滚动一行;
  9. ;(2) 对于2、3号功能,用 al 传送颜色值,(al) ∈{0,1,2,3,4,5,6,7}

  10. ;程序的流程:先安装好中断程序,再执行主程序
  11. ;1 主程序调用传递 ah,al的值,调用 int 7ch中段
  12. ;2 跳到目标地址,选择执行的子程序 call,如果ah的值错误,直接跳到第四部
  13. ;3 子程序执行完毕,ret返回目标地址的程序 0:200h处的中断程序
  14. ;4 中断程序执行完毕,iret,返回主程序
  15. ;5 主程序结束 mov ax, 4c00h      int 21h

  16. assume cs:code

  17. code segment

  18. do0:       
  19.                 push bx
  20.                 push cx
  21.                 push dx
  22.                 push si
  23.                 push di
  24.                 push ds
  25.                 push es
  26.                
  27.                 jmp short select      
  28.                
  29.         table dw sub1, sub2,sub3,sub4
  30.           
  31. select:
  32.                 mov dl, al

  33.                 cmp ah, 3
  34.                 ja goiret      ;判断传递的是否大于 3
  35.                
  36.                 mov bl, ah
  37.                 mov bh, 0
  38.                 add bx, bx           ;根据ah中的功能号计算对应子程序的地址在table表中的偏移
  39.                                                
  40.                 call word ptr table[bx]            ;调用对应的功能子程序
  41.                
  42. goiret: pop es
  43.                 pop ds
  44.                 pop di
  45.                 pop si
  46.                 pop        dx
  47.                 pop cx
  48.                 pop bx
  49.                
  50.                 iret
  51.                
  52.                
  53. ;功能子程序1:清屏               
  54. sub1:   mov ax, 0b800h
  55.                 mov es, ax
  56.                 mov di, 0
  57.                 mov cx, 2000
  58.                
  59.   sub1s:mov byte ptr es:[di], ' '
  60.                 add di, 2
  61.                 loop sub1s
  62.                 ret
  63.                
  64.                
  65. ;功能子程序2:设置前景色               
  66. sub2:        mov ax, 0b800h
  67.                 mov es, ax
  68.                 mov di, 1
  69.                 mov cx, 2000
  70.   sub2s:and byte ptr es:[di], 11111000b
  71.                 or es:[di], dl
  72.                 add di, 2
  73.                 loop sub2s
  74.                 ret
  75.                

  76. ;功能子程序3:设置背景色               
  77. sub3:       
  78.                 mov cl, 4
  79.                 shl dl, cl
  80.                 mov ax, 0b800h
  81.                 mov es, ax
  82.                 mov di, 1
  83.                 mov cx, 2000
  84.   sub3s:and byte ptr es:[di], 10001111b
  85.                 or es:[di], dl
  86.                 add di, 2
  87.                 loop sub3s
  88.                 ret


  89. ;功能子程序4:向上滚动一行               
  90. sub4:        mov ax, 0b800h
  91.                 mov ds, ax
  92.                 mov si, 160        ;ds:si指向第n+1行
  93.                
  94.                 mov es, ax       ;es:di指向第n行
  95.                 mov di, 0
  96.                
  97.                 cld
  98.                 mov cx, 24      ;共复制24行
  99.   sub4s:push cx
  100.                 mov cx, 160
  101.                 rep movsb     ;复制
  102.                 pop cx
  103.                 loop sub4s
  104.                
  105.                 mov cx, 80
  106.                 mov di, 0
  107.   sub4d:mov byte ptr es:[160*24+di], ' ' ;最后一行清空
  108.                 add di, 2
  109.                 loop sub4d
  110.                 ret
  111.                
  112. doends: nop               


  113. start:
  114.                 mov ax, cs
  115.                 mov ds, ax
  116.                 mov si, offset do0      ;设置源地址
  117.                
  118.                 mov ax, 0
  119.                 mov es, ax
  120.                 mov di, 200h                        ;设置目标地址
  121.                
  122.                 cld                                                ;df置零
  123.                 mov cx, offset doends - offset do0   
  124.                 rep movsb                                 ;把do0放到目标地址 0:200h
  125.                
  126.                 mov ax, 0
  127.                 mov es, ax
  128.                 mov word ptr es:[7ch*4], 0      
  129.                 mov word ptr es:[7ch*4+2], 20h   ;设置中断向量表
  130.                                                                                  ;注意:此时 cs = 20h, ip = 0
  131.                 mov ax, 4c00h
  132.                 int 21h
  133.                        
  134. code ends
  135. end start



  136. ; 主程序:-------------------------------------------------------------------------------------------------------
  137. ; assume cs:code
  138. ; ;入口参数说明:
  139. ; ;(1) 用 ah 寄存器传递功能号:0 表示清屏,1表示设置前景色,2 表示设置背景色,3 表示向上滚动一行;
  140. ; ;(2) 对于2、3号功能,用 al 传送颜色值,(al) ∈{0,1,2,3,4,5,6,7}
  141. ; code segment
  142. ; start:
  143.                 ; mov ah,02h
  144.                 ; mov al,04h
  145.                 ; int 7ch
  146.                
  147.                 ; mov ax, 4c00h
  148.                 ; int 21h
  149. ; code ends
  150. ; end start
  151. ; -----------------------------------------------------------------------------------------------------------------







  152. ;-------------------------------------------------------------------------------------------------------------------
  153. ; 注意事项!!!!!!!!!:
  154. ; 如果安装16.4给出的功能子程序的安装程序习惯采用下面图1安装结构会出问题,问题有两个:

  155. ;问题1:  table dw sub1……中SUB1存放的应该是子程序的偏移地址,这个偏移地址是相对于中断程序入口的,
  156. ;         而此时Sub1中存放的是相对于安装程序入口的地址。所以应该将被安装代码放到code段标号Start前边。

  157.         ; assume cs:code
  158.         ; code segment
  159.                 ; start:
  160.                         ; 安装程序
  161.                 ; ;--------------------------
  162.                 ; 被安装代码:
  163.                 ; ;--------------------------
  164.         ; code ends
  165.         ; end start
  166.           ; ==   图1   ==
  167.                   
  168. ; 问题2:在设置中断向量表的时候,0:[7ch*4]   Ip内存单元中的值应该设置为0,
  169.                                ; 0:[7ch*4+2]  CS内存单元中的值应该设置为 20h
  170.                                                           
  171.                 ; 原因:这个虽然和一般设定 mov ax, 0
  172.                                          ; mov es, ax
  173.                                                                  ; mov word ptr es:[7ch*4], 200h
  174.                                                                  ; mov word ptr es:[7ch*4+2], 0
  175.                                                                  
  176.                 ; 内存单元是一样的,都能找到目标中断程序的入口,但是,如果按照第二种方法
  177.                 ; 在主程序调用中断程序int7的时候,
  178.                 ; 相当于 (IP) = (n*4) = 200,(cs) = (n*4+2) = 0
  179.                        
  180.                 ; 于是 在执行中断程序中的 call word ptr table[bx],的过程中,当前的cs为0,ip为某个值
  181.                 ; 这个指令相当于 push ip, jmp cs:[table+bx],cs为0,那么内存空间0:[table+bx]为未知,程序出错
  182.                
  183.                 ; 如果按照第一种做法,此时cs:[table+bx], 是内存空间 20h:[table+bx], 是我们想得到的结果
复制代码


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

使用道具 举报

发表于 2013-3-20 17:12:20 | 显示全部楼层
红色在哪呀?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-20 17:19:30 | 显示全部楼层
正在帮你解决中……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-20 17:44:25 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-20 17:46:46 | 显示全部楼层
沉思者 发表于 2013-3-20 17:19
正在帮你解决中……

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

使用道具 举报

发表于 2013-3-20 19:22:07 | 显示全部楼层
要看回王爽的才知道。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-20 19:45:47 | 显示全部楼层
;问题1:  table dw sub1……中SUB1存放的应该是子程序的偏移地址,这个偏移地址是相对于中断程序入口的,
;         而此时Sub1中存放的是相对于安装程序入口的地址。所以应该将被安装代码放到code段标号Start前边。

        ; assume cs:code
        ; code segment
                ; start:
                        ; 安装程序
                ; ;--------------------------
                ; 被安装代码:
                ; ;--------------------------
        ; code ends
        ; end start
          ; ==   图1   ==
                  
; 问题2:在设置中断向量表的时候,0:[7ch*4]   Ip内存单元中的值应该设置为0,
                               ; 0:[7ch*4+2]  CS内存单元中的值应该设置为 20h
                                                          
                ; 原因:这个虽然和一般设定 mov ax, 0
                                         ; mov es, ax
                                                                 ; mov word ptr es:[7ch*4], 200h
                                                                 ; mov word ptr es:[7ch*4+2], 0
                                                                 
                ; 内存单元是一样的,都能找到目标中断程序的入口,但是,如果按照第二种方法
                ; 在主程序调用中断程序int7的时候,
                ; 相当于 (IP) = (n*4) = 200,(cs) = (n*4+2) = 0
                       
                ; 于是 在执行中断程序中的 call word ptr table[bx],的过程中,当前的cs为0,ip为某个值
                ; 这个指令相当于 push ip, jmp cs:[table+bx],cs为0,那么内存空间0:[table+bx]为未知,程序出错
               
                ; 如果按照第一种做法,此时cs:[table+bx], 是内存空间 20h:[table+bx], 是我们想得到的结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-20 21:26:48 | 显示全部楼层
大西洋1912 发表于 2013-3-20 17:46
灰常感谢

不好意思啊,我是个汇编新手,我很想帮你解决问题,可是我真的帮你解决不了……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-21 07:31:36 | 显示全部楼层
沉思者 发表于 2013-3-20 21:26
不好意思啊,我是个汇编新手,我很想帮你解决问题,可是我真的帮你解决不了……

大家一起讨论就好了,总会找到结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-21 07:34:00 | 显示全部楼层
大西洋1912 发表于 2013-3-21 07:31
大家一起讨论就好了,总会找到结果

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

使用道具 举报

 楼主| 发表于 2013-3-21 08:15:01 | 显示全部楼层
L]V[G 发表于 2013-3-20 19:45
;问题1:  table dw sub1……中SUB1存放的应该是子程序的偏移地址,这个偏移地址是相对于中断程序入口的,
...

具体怎么操作呢,刚刚按照你的说法搞了一边,好像不太行。难道是我理解错了(我的理解:mov word ptr es:[7ch*4],0  mov word ptr es:[7ch*4+2],200h)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-21 08:33:05 | 显示全部楼层
不好意思啊,我也是个汇编新手,我很想帮你解决问题,可是我真的帮你解决不了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-21 12:54:47 | 显示全部楼层
大西洋1912 发表于 2013-3-21 08:15
具体怎么操作呢,刚刚按照你的说法搞了一边,好像不太行。难道是我理解错了(我的理解:mov word ptr es: ...

是这个, mov word ptr es:[7ch*4],0  mov word ptr es:[7ch*4+2],20h,  此时cs:ip = 0020:0000
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-25 17:59:02 | 显示全部楼层
路过。。。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2013-3-25 18:37:57 | 显示全部楼层
看不懂。。。。。  好长。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-27 22:05:17 | 显示全部楼层
L]V[G 发表于 2013-3-21 13:00
我给个我自己打得程序你把,具体的要注意什么都有写了
具体干什么的,上面都有写,是书本的例子吧,也有一 ...

懂了。。。如果按我的写法需要将子程序和调用程序分为两个独立的程序来编写,也就是你说的问题一,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-22 00:10:30 | 显示全部楼层
本帖最后由 ddhssh 于 2021-2-22 00:15 编辑

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

使用道具 举报

发表于 2021-2-22 00:13:11 | 显示全部楼层
L]V[G 发表于 2013-3-20 19:45
;问题1:  table dw sub1……中SUB1存放的应该是子程序的偏移地址,这个偏移地址是相对于中断程序入口的,
...

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 14:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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