• 使用中断处理程序实现loop功能


    思路:

            assume cs:code
    
            code segment
            start:  mov ax, 0b800h
                    mov es, ax
                    mov di, 160*12
    
                    mov bx, offset s-offset se
                    mov cx, 80
                s:  mov byte ptr es:[di], '!'
                    add di, 2
                    int 7ch
                se: nop
    
                    mov ax, 4c00h;
                    int 21h
            code ends
            end start
    
            在7ch中断处理程序中,需要返回到s处来完成循环
            在跳转到7ch时,cs和ip入栈,ip存放的正是se的偏移量
            bx=s-se,现在我们得到了se的偏移量,只需要加上bx就能得到
            s的偏移量了
            因此在处理程序中,我们使用下面这段代码:
                show:       push bp
                            mov bp, sp
                            dec cx
                            jcxz showret
                            add [bp+2], bx
                showret:    pop bp
                            iret
                分析一下这段代码,访问栈段内存,所以要使用bp寄存器
                先保存他的值,然后让他指向栈顶,现在的栈中存储的数据是这样的:
                    +----+  每次将cx的值减1,当cx值为0时,恢复bp的值并返回
                    | bp |  如果cx的值不为0,就修改ip的值,将其加上bx,得到标号s的
                    +----+  偏移地址,然后恢复bp的值,执行iret指令,相当于
                    | ip |  pop ip      pop cs
                    +----+  这样一来,程序就会执行到s标号处
                    | cs |  如果add [bp+2], bx没有被执行,当iret执行完之后
                    +----+  就会执行到se处,这时程序也就结束了
                    |flag|  
                    +----+  完整的安装程序:
                    |····|  assume cs:code
                    +----+  
                            code segment
                            start:  mov ax, cs
                                    mov ds, ax
                                    mov si, offset show
                                    mov ax, 0
                                    mov es, ax
                                    mov di, 200h
                                    mov cx, offset showend-offset show
                                    cld
                                    rep movsb
    
                                    mov ax, 0
                                    mov es, ax
                                    mov word ptr es:[7ch*4], 200h
                                    mov word ptr es:[7ch*4+2], 0
    
                                    mov ax, 4c00h
                                    int 21h
    
                            show:   push bp
                                    mov bp, sp
                                    dec cx
                                    jcxz showret
                                    add [bp+2], bx
                            showret:pop bp
                                    iret
                            showend:nop
    
                            code ends
                            end start
    

    t2.asm:  

    assume cs:code
    
    code segment
    start:  mov ax, 0b800h
            mov es, ax
            mov di, 160*12
    
            mov bx, offset s-offset se
            mov cx, 80
        s:  mov byte ptr es:[di], '!'
            mov byte ptr es:[di+1], 02h
            add di, 2
            int 7ch
        se: nop
    
            mov ax, 4c00h;
            int 21h
    code ends
    end start
    t1.asm(安装程序)
    
    assume cs:code
    
    code segment
    start:  mov ax, cs
            mov ds, ax
            mov si, offset show
            mov ax, 0
            mov es, ax
            mov di, 200h
            mov cx, offset showend-offset show
            cld
            rep movsb
    
            mov ax, 0
            mov es, ax
            mov word ptr es:[7ch*4], 200h
            mov word ptr es:[7ch*4+2], 0
    
            mov ax, 4c00h
            int 21h
    
    show:   push bp
            mov bp, sp
            dec cx
            jcxz showret
            add [bp+2], bx
    showret:pop bp
            iret
    showend:nop
    
    code ends
    end start  
    

      

    运行过程:

    先运行t1.exe,安装中断程序

    再通过debug调试t2.exe

    运行至int 7ch处时如下所示:

     

     可以看出此时的CS 、IP、和栈中的内容,栈中的数值为之前单步中断保存的flag、CS、IP等寄存器的值,再执行一步-t,进入中断服务函数,如下所示

     此时栈顶指针为FFFA(指向1C),其中076A为保存的CS,001C为保存的IP值,继续执行两次-t,看到:

    SP变为FFF8指向(00),BP的值0000入栈后,将SP的值赋值给了BP。继续多次执行-t后如图:

     栈中保存的IP值已经被重新赋值为000E(001c+FFF2),继续执行如下:

     将栈中的BP、IP、CS、flag寄存器依次出栈,栈顶指针SP变为0000.程序将会跳到S处继续运行,

    至此,完成了第一次循环。后面的循环调用过程类似

  • 相关阅读:
    Python接口自动化之request请求封装
    AI缘起——达特茅斯会议
    AirtestProject测试框架
    强化学习落地:竞态场景下基于锁机制的闲置端口查用
    多智能体强化学习入门Qmix
    代码回滚----git reset 和 git revert 使用
    requestAnimationFrame
    深度剖析-事件循环event
    Ubuntu18.04安装ES也就是ELK
    Ubuntu18.04+kafka
  • 原文地址:https://www.cnblogs.com/lh03061238/p/13305218.html
Copyright © 2020-2023  润新知