在32位Open Watcom C中生成FAR跳转指令



我需要生成一条远跳指令来跳到另一个ISR(中断服务例程)。我正在开发一个32位的FreeDOS应用程序。

在阅读了OW手册(cguide.pdf和clr.pdf)后,我找到了两种方法,使在没有任何警告或错误的情况下成功编译

    /* Code Snippet #1 */
    #pragma aux old08 aborts ;
    void (__interrupt __far *old08)(void);      // function pointer declaration

    void __interrupt __far new08(void) {
           /* Do some processing here ... */
           (*old08)();  /* OW will now generate a jump inst. instead of call*/
     }

我发现的另一种方法是:

      /* Code Snippet #2 */
      static void jumpToOld08(void);         
      # pragma aux jumpToOld08 = 
             ".686p"            
             "                DB      0xEA"            
             "off_old08       DD      0"                    
             "sel_old08       DW      0"     ;             

      void __interrupt __far new08(void){
               /* Do some processing here ... */
               jumpToOld08();   
      }
      extern unsigned short sel_old08;
      extern unsigned int off_old08;
      sel_old08 = ( __segment )FP_SEG(old08);
      off_old08 = FP_OFF(old08);        

现在我的问题是,在以上两种方式中,哪个更正确或更好?有什么想法或意见吗?

有其他方法可以做到这一点吗?

interrupt函数总是很远。

就指令本身而言,手动构建的远跳转似乎是正确的,然而,我敢打赌,简单的跳转(而不是调用)不会删除new08()之前在其序言时保存在堆栈上的内容(这可能会有很多寄存器,最重要的是,还有一个隐藏的返回地址,old08()必须返回到该地址!)。

为什么这么有创意?

    #include <dos.h>
    void _chain_intr( void (__interrupt __far *func)(void) );

此函数可用于跳转到链中的另一个中断处理程序。此函数永远不会返回。它弹出interrupt关键字保存的所有寄存器,并跳到处理程序。当func指定的中断处理程序接收到控制时,堆栈和寄存器看起来就像中断刚刚发生一样。

此函数只能在用interrupt关键字声明的函数中使用。

跳转而不是调用的优势在irq处理程序中并不明显,但在软件中断处理程序中肯定是如此。链中的下一个软件中断处理程序希望cpu寄存器包含一些信息,例如传递给它的参数,因此在跳到下一个处理程序chaintr之前,将恢复所有cpu寄存器,就好像下一个处理器直接接收控制一样。

我可能会写这样的东西:

void far_jump (uint32_t offset, uint16_t selector)
{
    /* remove the (callee's) stack frame including the return address by manipulating esp & ebp */
    /* the top of the stack now points to offset:selector */
    _asm
    {
        retf    ; or whatever the asm syntax dictates
    }
    /* esp & ebp will now point to the caller's stack frame */
}

我记得32位模式将把选择器作为32位单元来推送和弹出,即使只使用低16位。

相关内容

  • 没有找到相关文章

最新更新