鱼C论坛

 找回密码
 立即注册
查看: 2336|回复: 5

王爽汇编实验16的问题弄不懂啊

[复制链接]
发表于 2012-11-25 22:05:28 | 显示全部楼层 |阅读模式
1鱼币
搞不明白啊怎么回事下面的CALL WORD PTR TABLE[BX]运行起来和CS不一样啊。解决方法我只会用OFFSET了那学这表有毛用啊
求高手前辈们指教啊
assume cs:code
code segment
start: mov ax,0
mov es,ax
mov ax,cs
mov ds,ax
cli
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
sti
mov si,offset sj
mov di,200h
mov cx,offset sjends-offset sj
cld
rep movsb
mov ax,0
mov ah,2
int 7ch
mov ax,4c00h
int 21h
org 200h
sj:jmp short rukou
table dw sub0,sub1,sub2,sub3
rukou:
cmp ah,3
ja ko
push bx
mov bx,0
mov bh,ah
add bx,bx
call word ptr table[bx](其它的先不管主要是这句的问题,郁闷了table[bx]怎么就跳到206去了。。。按理说u应该啊,按我的理解应该跳到SUB2的偏移地址里面去啊)
pop bx
ko: iret
sub0: push es
push di
push cx
push bx
mov bx,0b800h
mov es,bx
mov bh,' '
mov di,0
mov cx,2000
sub0s: mov byte ptr es:[di],bh
add di,2
loop sub0s
pop bx
pop cx
pop di
pop es
ret
sub1: push ax
push es
push di
push cx
mov ax,0b800h
mov es,ax
mov cx,2000
mov di,1
sub1s: and byte ptr es:[di],00000000b
or byte ptr es:[di],00000111b
add di,2
loop sub1s
pop cx
pop di
pop es
pop ax
ret
sub2:
push ax
push es
push di
push cx
mov ax,0b800h
mov es,ax
mov cx,2000
mov di,1
sub2s: and byte ptr es:[di],00000000b
or byte ptr es:[di],01111000b
add di,2
loop sub1s
pop cx
pop di
pop es
pop ax
ret
sub3: push ax
push es
push ds
push di
push cx
mov ax,0b800h
mov es,ax
mov ds,ax
mov si,160
mov di,0
mov cx,24
sub3s: push cx
mov cx,160
cld
rep movsb
pop cx
mov si,0
mov cx,80
sub3ss: mov byte ptr es:[23*160+si],' '
add si,2
loop sub3ss
pop cx
pop di
pop ds
pop es
pop ax
ret
sjends:nop
code ends
end start

小甲鱼最新课程 -> https://ilovefishc.com
发表于 2012-11-26 11:28:42 | 显示全部楼层
代码写的有点乱。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-11-26 20:24:24 | 显示全部楼层
......自学又是赶时间学,自学自用的、。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2012-12-21 09:02:50 | 显示全部楼层
应该是mov bl,ah
而不是mov bh,ah吧
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-13 22:13:20 | 显示全部楼层
我来给个,注意事项注释什么的都有了,应该包含了你的疑问
  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. assume cs:code

  11. code segment

  12. do0:       
  13.                 push bx
  14.                 push cx
  15.                 push dx
  16.                 push si
  17.                 push di
  18.                 push ds
  19.                 push es
  20.                
  21.                 jmp short select      
  22.                
  23.         table dw sub1, sub2,sub3,sub4
  24.           
  25. select:
  26.                 mov dl, al

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

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


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


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



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




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

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

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

,我自己敲的


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-8-29 10:31:39 | 显示全部楼层
{:1_1:}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-1 18:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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