>>143
>>180
ソースを少し調べてみたので報告。コンパイルできるようなら以下の変更箇所確認して試してみるとよいかも。
それと、少し古いソース(np21w-0.86-rev26beta)で調べたので行数は違うかもです。
修正箇所はia32/cpu_mem.cの220行目からの関数cpu_stack_push_check内の229、230行目
start = sp - len;
limit = is32bit ? 0xffffffff : 0x0000ffff;

sp = (sp - 1) & (SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff);
start = (sp - len) & (SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff);
limit = sdp->u.seg.g ? 0xffffffff : 0x0000ffff;

に変更。SEG_IS_32BIT(sdp)のところは、意味的にはis32bitの方がよいのかも?(計算上は同じです)
一応変更の根拠としては、
まず検証環境として、config.sysに以下を追加

device=a:\ERCACHE.EXE /HM /M=A5-A7,D0-D3 /HSB-

これで、修正前のnp21wでtriple faultが発生するのを確認。
この状況でこの関数に入ってくるとき、sp=0x0000、len=0x0028になっており、修正前だとstartが0xffffffd8になって、
その後の(start > sp)の条件に引っかかってしまいます。
しかし、スタックのプッシュ処理は最初に格納するサイズ分減算し、そこからサイズ分書き込むので、
実際にはアドレス0x0000に書き込まれることはなくそういう意味では保護範囲のチェックとしては必ずしも適切ではないといえます。
ということで、変数spを実際に値が書かれる最終アドレスに書き換えてその上でアドレス判定をするように変更しています。

ついでに、limitの上限値の判定がセグメントディスクリプタのD/Bビットと見受けたので、Gビットに変更しています。
これについては関連して他の場所も直した方がよいのでは?と思うところがいくつかあったのですが、
十分に検証できていないのでそのままにしています。