我已经在MMIX中编写了setjmp和longjmp的实现(不使用名称mangling)。我也是手工组装的。有人能发现什么错误吗?
// 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 // AFFE0018
POP 0,0 // F8000000
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
SET $255,$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
POP 2,0 // F8020000寄存器栈是这里最难的部分。SAVE和UNSAVE包含的所有内容本质上都只是“正确设置寄存器堆栈指针”;在此之后,完全不用花时间来修复其他寄存器并返回。
如果您有任何其他问题,我很乐意解释我的每一个四分码的原因。
发布于 2021-04-25 17:50:00
看起来您的setjmp将jmp_buf参数作为$0 --但是jmp_buf是如何定义的--例如,它需要多少空间?
另外,longjmp接受两个参数--相同的jmp_buf和一个int --我不认为$1用于longjmp中的第二个输入参数
您可以找到命令行工具在https://mmix.cs.hm.edu/exe上运行MMIX程序来测试您的实现--还有一个Windows调试器--您能显示调用setjmp和longjmp的示例MMIX代码吗?
https://codereview.stackexchange.com/questions/256527
复制相似问题