kyowjw01 发表于 2017-6-9 23:13:55

实验15 安装新的int9中断例程 及其 切换颜色程序的问题

实验15 安装新的int9中断例程 及其 切换颜色程序的问题
为什么我在虚拟机敲了两三遍还是没有预想的结果,一个代码是pdf上的源码,一个是答案的源码。执行后,什么效果都没有。谁能告诉我该如何解决?

kyowjw01 发表于 2017-6-9 23:19:45

{:10_266:}难道我太小白了吗?

人造人 发表于 2017-6-10 01:34:11

截图

kyowjw01 发表于 2017-6-10 09:25:42

kyowjw01 发表于 2017-6-10 09:28:56

人造人 发表于 2017-6-10 01:34
截图


又忘记如何回复贴了,第二次了。。。图已附上{:10_282:}

kyowjw01 发表于 2017-6-10 09:35:47

本帖最后由 kyowjw01 于 2017-6-10 09:39 编辑

人造人 发表于 2017-6-10 01:34
截图

截的图中的代码是 王爽《汇编语言》第二版习题答案的实验15中的代码。不过这参考答案不一定会准确,因为检测点15.1(2)的答案就有问题,矫正后才会有效果。不过《汇编语言》(第三版)的pdf 15.5和这个实验15参考代码都没有效果,应该没这么邪门吧!{:10_291:}

人造人 发表于 2017-6-10 11:51:26

kyowjw01 发表于 2017-6-10 09:35
截的图中的代码是 王爽《汇编语言》第二版习题答案的实验15中的代码。不过这参考答案不一定会准确,因 ...

还要发代码,不然,我就需要一个字母一个字母的从图片上抄了^_^

kyowjw01 发表于 2017-6-10 14:46:53

人造人 发表于 2017-6-10 11:51
还要发代码,不然,我就需要一个字母一个字母的从图片上抄了^_^

;任务:安装一个新的int 9中断例程

;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕的'A',其他键照常处理

assume cs:code

stack segment

   db 128 dup (0)

stack ends

code segment

start:   mov ax,stack

   mov ss,ax

   mov sp,128

   push cs

   pop ds

   mov ax,0

   mov es,ax

   mov si,offset int9   ;设置ds:si指向源地址

   mov di,204h            ;设置es:di指向目标地址

   mov cx,offset int9end-offset int9    ;设置cx为传输长度

   cld                ;设置传输方向为正

   rep movsb

;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中

   push es:

   pop es:

   push es:

   pop es:

;在中断向量表中设置新的int 9中断例程的入口地址

   cli                ;设置IF=0屏蔽中断

   mov word ptr es:,204h

   mov word ptr es:,0

   sti                ;设置IF=1不屏蔽中断

;结束

   mov ax,4c00h

   int 21h

;新的int 9中断例程

int9:    push ax

   push bx

   push cx

   push es

   in al,60h          ;从端口60h读出键盘输入

;对int指令进行模拟,调用原来的int 9中断例程

   pushf                  ;标志寄存器入栈

   call dword ptr cs:    ;CS,IP入栈,(IP)=cs:,(CS)=0

;如果是A断码,改变当前屏幕的显示字符

   cmp al,9eh             ;和A的断码(1eh+80h)比较

   jne int9ret            ;不等于A时转移

   mov ax,0b800h

   mov es,ax

   mov bx,0

   mov cx,2000

s:   mov byte ptr es:,41h    ;将A的ASCII码写入,改变字符

   add bx,2

   loop s

int9ret:pop es

   pop cx

   pop bx

   pop ax

   iret

int9end:nop

code ends

end start

人造人 发表于 2017-6-10 15:41:25

kyowjw01 发表于 2017-6-10 14:46
;任务:安装一个新的int 9中断例程

;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕 ...

你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下


;任务:安装一个新的int 9中断例程
;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕的'A',其他键照常处理
assume cs:code

stack segment
   db 128 dup (0)
stack ends

code segment

start:
        mov ax, stack
        mov ss, ax
        mov sp, 128

        push cs
        pop ds

        mov ax, 0
        mov es, ax
        mov si, offset int9        ;设置ds:si指向源地址
        mov di, 204h                ;设置es:di指向目标地址
        mov cx, offset int9end - offset int9        ;设置cx为传输长度

        cld                ;设置传输方向为正
        rep movsb

        ;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中
        push es:
        pop es:
        push es:
        pop es:

        ;在中断向量表中设置新的int 9中断例程的入口地址
        cli                ;设置IF=0屏蔽中断
        mov word ptr es:, 204h
        mov word ptr es:, 0
        sti                ;设置IF=1不屏蔽中断

        ;结束
        mov ax, 4c00h
        int 21h

       
;新的int 9中断例程
int9:
        push ax
        push bx
        push cx
        push es

        in al, 60h        ;从端口60h读出键盘输入

        ;对int指令进行模拟,调用原来的int 9中断例程
        pushf                ;标志寄存器入栈
        call dword ptr cs:        ;CS,IP入栈,(IP)=cs:,(CS)=0

        ;如果是A断码,改变当前屏幕的显示字符
        cmp al, 1eh + 80h                ;和A的断码(1eh+80h)比较
        jne int9ret                ;不等于A时转移

        mov ax, 0b800h
        mov es, ax
        mov bx, 0
        mov cx, 2000
s:
        mov byte ptr es:, 'A'        ;将A的ASCII码写入,改变字符
        add bx, 2
        loop s

int9ret:
        pop es
        pop cx
        pop bx
        pop ax
        iret

int9end:
        nop

code ends
end start



我在纯DOS下试了,可以


在Windows 下cmd 应该没有调用 int9,所以看不到效果,使用debug查看

kyowjw01 发表于 2017-6-10 16:21:40

人造人 发表于 2017-6-10 15:41
你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下


请教一下如何纯DOS,像你这样子的。我用的是虚拟机XP(x86)

kyowjw01 发表于 2017-6-10 16:38:32

人造人 发表于 2017-6-10 15:41
你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下


出来了,谢谢,像你第二张用debug可以

kyowjw01 发表于 2017-6-10 16:39:17

人造人 发表于 2017-6-10 15:41
你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下


我现在的疑问是不知道怎么进入纯dos,应该不是alt+enter全屏吧?

人造人 发表于 2017-6-10 19:20:53

kyowjw01 发表于 2017-6-10 16:39
我现在的疑问是不知道怎么进入纯dos,应该不是alt+enter全屏吧?

在虚拟机中安装一个DOS系统

kyowjw01 发表于 2017-6-10 20:00:16

人造人 发表于 2017-6-10 19:20
在虚拟机中安装一个DOS系统

但我不知道怎么共享文件=。=|||,也不知道怎么把编译器丢进去{:10_269:}

人造人 发表于 2017-6-10 20:05:29

kyowjw01 发表于 2017-6-10 20:00
但我不知道怎么共享文件=。=|||,也不知道怎么把编译器丢进去

kyowjw01 发表于 2017-6-12 10:40:08

本帖最后由 kyowjw01 于 2017-6-12 11:02 编辑

人造人 发表于 2017-6-10 20:05


assume cs:code

stack segment
db 128 dup (0)
stack ends

code segment
start:       
                mov ax,stack
                mov ss,ax
                mov sp,128
               
                push cs
                pop ds
               
                mov ax,0
                mov es,ax
               
                mov si,offset int9                                        ;设置ds:si指向源地址
                mov di,204h                                                        ;设置es:di指向目的地址
                mov cx,offset int9end-offset int9        ;设置cx为传输长度
                cld                                                                        ;设置传输方向为正
                rep movsb
;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中
                push es:
                pop es:
                push es:
                pop es:
;在中断向量表中设置新的int 9中断例程的入口地址
                cli                ;设置IF=0屏蔽中断
                mov word ptr es:,204h
                mov word ptr es:,0
                sti                ;设置IF=1不屏蔽中断
;结束
                mov ax,4c00h
                int 21h
;新的int 9中断例程
int9:       
                push ax
                push bx
                push cx
                push es
               
                in al,60h                                        ;从端口60h读出键盘输入
;对int指令进行模拟,调用原来的int 9中断例程
                pushf                                                ;标志寄存器入栈
                call dword ptr cs:        ;CS,IP入栈,(IP)=cs:,当此中断例程执行时(CS)=0
;如果是A断码,改变当前屏幕的显示字符
                cmp al,3bh                                        ;F1的扫描码为3bh
                jne int9ret                                        ;不等于扫描码(断码)时转移
               
                mov ax,0b800h
                mov es,ax
                mov bx,1                                        ;奇数为颜色
                mov cx,2000
        s:                                                        ;不知道为何,如果这边不打回车,就出不来效果。
                inc byte ptr es:
                add bx,2
                loop s
               
int9ret:
                pop es
                pop cx
                pop bx
                pop ax
                iret
               
int9end:nop

code ends
end start

花了一个多小时,才知道在代码段的标号s处(56行)打回车才出效果。
但是,我还是不知道为什么在代码段的标号s处(56行)中不打回车换行就不会出现变色效果?

想传图,但是点击发送,不小心点了撤销,提示说发图上限了。。。{:10_277:}

kyowjw01 发表于 2017-6-12 10:44:09

人造人 发表于 2017-6-10 20:05


这个是F1切换整个颜色的代码。

kyowjw02 发表于 2017-6-12 11:33:11

人造人 发表于 2017-6-10 20:05


上图!

人造人 发表于 2017-6-12 12:38:56

kyowjw02 发表于 2017-6-12 11:33
上图!

这个和换行没有关系
关了cmd,重新开一下
一个cmd只能执行一次这个程序,你说这是为什么呢?仔细看程序,你会知道答案的

kyowjw01 发表于 2017-6-12 14:07:50

人造人 发表于 2017-6-12 12:38
这个和换行没有关系
关了cmd,重新开一下
一个cmd只能执行一次这个程序,你说这是为什么呢?仔细看程序 ...

又看了一遍,还是不明白。现在只知道一个cmd只能执行一次这个程序。因为是模拟的中断?
页: [1] 2 3
查看完整版本: 实验15 安装新的int9中断例程 及其 切换颜色程序的问题