鱼C论坛

 找回密码
 立即注册
查看: 3446|回复: 8

[汇编作业] 检测点 15.1

[复制链接]
发表于 2019-3-27 16:32:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 奥普瓯江 于 2019-3-27 16:43 编辑

(1)仔细分析一下上面的int 9 中断例程, 看看是否可以精简一下?
                其实在我们的int 9 中断例程中, 模拟int 指令调用原int 9 中断例程的程序段是可以精简的, 因为在进入中断例程后, IF 和 TF都已经置0,没有必要在进行设置了。
对于程序段:

  1.                 pushf
  2.                 pushf
  3.                 pop ax
  4.                 and  ah, 11111100b
  5.                 push ax
  6.                 popf
  7.                 call dword ptr ds:[0]
复制代码


可以精简为:
  1.                 pushf                                                ;因为下面的返回中call模拟int 9h 程序返回时需要 寄存器数据,所以这里需要向栈中输入一个cf寄存器数据供下面call中的iret返回使用
  2.                 call dword ptr ds:[0]                ;这个是必须有的所以他不能动模拟int 9 程序
  3.        
复制代码




原程序如下:
  1. assume cs:code, ds:data_1, ss:stack

  2. data_1 segment
  3.                 dw 0,0
  4. data_1 ends

  5. stack segment
  6.                 db 128 dup (0)
  7. stack ends


  8. code segment
  9. start:
  10.                 mov ax, data_1    ;数据段
  11.                 mov ds, ax
  12.                 mov si, 0
  13.                
  14.                 mov ax, stack                ;栈定义  ,这里定义不定义栈其实无所谓,因为编译器会自动定义栈位ffff
  15.                 mov ss, ax
  16.                 mov sp, 128
  17.                
  18.                 mov ax, 0
  19.                 mov es, ax
  20.                 ;把int 9h中断限量表中的地址传给数据段0、1和2、3, 这样中断限量表中的int 9h 中断就不会消失了,他的地址一致会储存在数据段中随时让我们可以调用
  21.                 push es:[9 * 4]                ;低位为偏移地址
  22.                 pop  ds:[0]                        ;ds低位为偏移地址储存
  23.                
  24.                 push es:[9 * 4 + 2] ;高位为段地址
  25.                 pop         ds:[2]                        ;ds高位为短地址储存
  26.                
  27.                 mov word ptr es:[9 * 4], offset int9       ;偏移地址
  28.                 mov word ptr es:[9 * 4 + 2], cs                          ;短地址每个地址占两个字节一共4个字节
  29.                
  30.                
  31.                
  32.                
  33.                 mov ax, 0b800h
  34.                 mov es, ax
  35.                 mov ah, 'a'
  36. s:
  37.                 mov byte ptr es:[160 * 12 + 40 * 2], ah
  38.                 inc ah
  39.                 call jump_1
  40.                 cmp ah, 'z'
  41.                 jna s
  42.                
  43.                 ;把中断向量表中的地址恢复成初始地址
  44.                 mov ax, 0
  45.                 mov es, ax
  46.                
  47.                 push word ptr ds:[0]
  48.                 pop word ptr es:[9 * 4]
  49.                
  50.                 push word ptr ds:[2]
  51.                 pop word ptr es:[9 * 4 + 2]
  52.                
  53.                 mov ax, 4c00h
  54.                 int 21h
  55.                
  56.                
  57. jump_1:
  58.                 push ax
  59.                 push dx
  60.                 mov ax, 0
  61.                 mov dx, 1000h
  62. jump_2:
  63.                 sub ax, 1
  64.                 sbb dx, 0
  65.                
  66.                 cmp ax, 0                ;内循环
  67.                 jne jump_2
  68.                
  69.                 cmp dx, 0                ;外循环
  70.                 jne jump_2
  71.                
  72.                 pop dx
  73.                 pop ax
  74.                 ret
  75. int9:
  76.                 push ax
  77.                 push es
  78.                 push ds
  79.                
  80.                 pushf
  81.                 pushf
  82.                
  83.                 pop ax
  84.                 and ax, 11111100b
  85.                 push ax
  86.                 popf
  87.                 call dword ptr ds:[0]
  88.                
  89.                
  90.                 in al, 60h

  91.                 cmp al, 1
  92.                 jne good
  93.                
  94.                 inc byte ptr es:[160 * 12 + 40 * 2 + 1]
  95.                
  96. good:
  97.                 pop ds
  98.                 pop es
  99.                 pop ax
  100.                 iret
  101.                
  102. code ends
  103. end start
复制代码


int 9临时模拟图示这个是自己看的
绘图1.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-5-8 09:16:22 | 显示全部楼层
int9段我有疑问
push了ax、es、ds,再pushf两次,pop,push、popf,call dw
那么栈中内容,低到高,存着ip、cs、pushf、ds、es、ax
然后跳转到good,就能直接pop
ds、es、ax?
怎么看都是错的吧!
还有ip、cs、pushf内容隔着呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-8 09:28:40 | 显示全部楼层
看视频的时候我就觉得有问题
栈中内容,低到高,存着ip、cs、pushf、ds、es、ax
接下来由good,完成了6次pop,但是顺序不对
good:
                pop ds   ;看顺序应该是ip
                pop es    ;cs
                pop ax    ;pushf
                iret    ;完成了ds给ip,es给cs,ax给了标志寄存器
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-8 10:02:03 | 显示全部楼层
assume cs:code, ds:data_1, ss:stack

data_1 segment
                dw 0,0
data_1 ends

stack segment
                db 128 dup (0)
stack ends


code segment
start:
                mov ax, data_1    ;数据段
                mov ds, ax
                mov si, 0
               
                mov ax, stack                ;栈定义  ,这里定义不定义栈其实无所谓,因为编译器会自动定义栈位ffff
                mov ss, ax
                mov sp, 128
               
                mov ax, 0
                mov es, ax
                ;把int 9h中断限量表中的地址传给数据段0、1和2、3, 这样中断限量表中的int 9h 中断就不会消失了,他的地址一致会储存在数据段中随时让我们可以调用
                push es:[9 * 4]                ;低位为偏移地址
                pop  ds:[0]                        ;ds低位为偏移地址储存
               
                push es:[9 * 4 + 2] ;高位为段地址
                pop  ds:[2]                        ;ds高位为短地址储存
               
                mov word ptr es:[9 * 4], offset int9       ;偏移地址
                mov word ptr es:[9 * 4 + 2], cs                          ;短地址每个地址占两个字节一共4个字节
               
               
               
               
                mov ax, 0b800h
                mov es, ax
                mov ah, 'a'
s:
                mov byte ptr es:[160 * 12 + 40 * 2], ah
                inc ah
                call jump_1
                cmp ah, 'z'
                jna s
               
                ;把中断向量表中的地址恢复成初始地址
                mov ax, 0
                mov es, ax
               
                push word ptr ds:[0]
                pop word ptr es:[9 * 4]
               
                push word ptr ds:[2]
                pop word ptr es:[9 * 4 + 2]
               
                mov ax, 4c00h
                int 21h
               
               
jump_1:
                push ax
                push dx
                mov ax, 0
                mov dx, 1000h
jump_2:
                sub ax, 1
                sbb dx, 0
               
                cmp ax, 0                ;内循环
                jne jump_2
               
                cmp dx, 0                ;外循环
                jne jump_2
               
                pop dx
                pop ax
                ret
int9:
                pushf
                               
                                push ax
                               
                                pushf
                                pop ax
                and ax, 11111100b
                push ax
                popf
                               
                                pop ax

                call dword ptr ds:[0]
                               
                push ax
                push es
                push ds
              
               
                in al, 60h

                cmp al, 1
                jne good
               
                inc byte ptr es:[160 * 12 + 40 * 2 + 1]
               
good:
                pop ds
                pop es
                pop ax
                iret
               
code ends
end start
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-8 10:27:34 | 显示全部楼层
我只改动了int9的内容

int9:
                pushf         ;标志寄存器入栈,栈内数据低到高:flag
                                
                push ax        ;ax入栈保护,栈内数据低到高:ax,flag
                                
                pushf        ;标志寄存器再次入栈,栈内数据低到高:flag,ax,flag

                pop ax        ;标志寄存器,弹出给ax,栈内数据低到高:ax,flag

                and ah, 11111100b        ;这里是楼主的88行,代码写错,TF和IF清零,应该使用高位ah,栈内数据低到高:ax,flag
               
                push ax        ;TF、IF置零后的寄存器数据在ax中,入栈,栈内数据低到高:ax(flag),ax,flag
               
                popf                ;新的flag置零完毕,栈内数据低到高:ax,flag
                                
                pop ax        ;还原ax的值,栈内数据低到高:flag

                call dword ptr ds:[0]                ;双字call命令,CS入栈,IP入栈,栈内数据低到高:ip,cs,flag
                                                        ;此时栈内有flag标志寄存器,cs代码段地址,ip偏移地址,相当于完成了int 9的前3步,call命令完成了int 9的第四步
                                                        ;从此刻开始,模拟调用了int        9的中断命令,栈内数据低到高:ip,cs,flag
                                
                push ax                                ;入栈各个寄存器
                push es
                push ds                                ;入栈三个,栈内数据低到高:ds,es,ax,ip,cs,flag
              
               
                in al, 60h                                ;寄存器保存好,开始运行键盘的外部中断,此步为读取端口,栈内数据低到高:ds,es,ax,ip,cs,flag

                cmp al, 1                                ;比较esc的通码,栈内数据低到高:ds,es,ax,ip,cs,flag
         
                jne good                                ;不是则跳转good,是则向下执行变色
               
                inc byte ptr es:[160 * 12 + 40 * 2 + 1]        ;变色
               
good:
                pop ds                                ;弹出ds,栈内数据低到高:es,ax,ip,cs,flag
                pop es                                ;弹出es,栈内数据低到高:ax,ip,cs,flag
                pop ax                                ;弹出ax,栈内数据低到高:ip,cs,flag
                iret                                        ;恢复ip、恢复cs、恢复flag,此时栈内清空,模拟中断完成
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-8 10:29:13 | 显示全部楼层
楼主88行的ax要改成ah,或者数据改成1111110011111111b
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-8 20:02:39 | 显示全部楼层
Aslcwd 发表于 2019-5-8 09:16
int9段我有疑问
push了ax、es、ds,再pushf两次,pop,push、popf,call dw
那么栈中内容,低到高,存着i ...

2019-05-08_19-30-34.png

这里面这个call dword ptr ds:[0]是用来模拟int 9 命令的int 9 命令的运作原理是
绘图1.jpg
所以在int 9 结束的时候已经把 你所说的 ip cs pushf都已经释放了所以不存在隔着的情况
在这里你指出的那个and ax,11111100b那个是我错了这个应该是ah我应该改正
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-10 16:54:01 | 显示全部楼层
奥普瓯江 发表于 2019-5-8 20:02
这里面这个call dword ptr ds:[0]是用来模拟int 9 命令的int 9 命令的运作原理是

所以在int 9 结 ...

call的命令发出,其实是去执行真正的int 9去了,执行完毕还要iret,回到call下面那一行是吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-11 10:43:56 | 显示全部楼层
Aslcwd 发表于 2019-5-10 16:54
call的命令发出,其实是去执行真正的int 9去了,执行完毕还要iret,回到call下面那一行是吗?

嗯嗯是的,执行call下面的 in al, 61h
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-26 20:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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