首页 > 解决方案 > mmix 中的 setjmp 和 longjmp 实现

问题描述

我在 MMIX 中编写了 setjmp 和 longjmp 的实现(假设没有名称修改)。我也是手工组装的。
有没有人能发现的错误?

    // Memory stack pointer is stored in $254.
    // jmp_buf is rO, next address after setjmp call, memory stack pointer,
    // frame pointer, then possibly other data (for sigsetjmp/siglongjmp).
    // rG is preserved over a longjmp call
    // (not that it should change over one, anyway)
setjmp IS @
    GET    $1,rO            // FE01000A
    STOU   $1,$0,0          // AF010000
    GET    $1,rJ            // FE010004
    STOU   $1,$0,8          // AF010008
    STOU   $254,$0,16       // AFFE0010
    STOU   $253,$0,24       // AFFD0018
    SETL   $0,0             // E3000000
    POP    1,0              // F8010000
longjmp IS @
    LDOU   $254,$0,0        // 8FFE0000
    SAVE   $255,0           // FAFF0000
    GET    $1,rG            // FE000013
    // why 15? We save 13 special registers, two local registers,
    // and the number 2, as well as any global registers.
    // That's 256-rG + 16, and we add only 15 because $255 is the address
    // of the saved rGA.
    SETL   $0,271           // E300010F
    SUBU   $1,$1,$0         // 26010100
    SLU    $1,$1,3          // 39000003
    // now $255 is topmost saved register, $255+$1 is bottommost such,
    // $254 is rO after.
    SUBU   $0,$254,$1       // 2600FE01
    LDOU   $2,$255,$1       // 8E02FF01
    STOU   $2,$0,$1         // AE020001
    INCL   $1,8             // E7010008
    PBNZ   $1,@-12          // 5B01FFFD
    OR     $255,$0,0        // C1FF0000
    UNSAVE 0,$255           // FB0000FF
    // now we have restored rO, but not other stuff
    LDOU   $253,$0,24       // 8FFD0018
    LDOU   $254,$0,16       // 8FFE0010
    LDOU   $0,$0,8          // 8F000008
    PUT    rJ,$0            // F6040000
    OR     $0,$1,0          // C1000100
    POP    1,0              // F8010000

寄存器堆栈是这里的难点。SAVE和包容之间的一切UNSAVE本质上只是“rO正确设置”;之后,完全不需要时间来修复其他寄存器并返回。

如果您有任何其他问题,我很乐意解释我对该代码的每个 tetra 的原因。

标签: assemblysetjmpmmix

解决方案


推荐阅读