TSSを用いたコンテキスト切り替えについて

ltrですっとぶ件についてはポインタ演算のミスという事でカタがついたが、TSSを使ったコンテキスト切り替えの一般的な実装方法というものが良くわからない。

不特定のプロセスへの動的なスケジューリング情報を元に次の切り替え先プロセスを決める時、1プロセス:1TSSである実装はどのように書くべきなのだろう?
直ぐに思いつく方法としてはTSS毎にTSSディスクリプタを用意する方法だが、ポインタ経由のfar jumpのやり方が解らない。

このサイトで紹介されている方法やlinux-1.0のソースコードでは確かにポインタ経由でfar jumpしているようなのだが、実際に手元で試すとうまくいかないのだ:
http://www.acm.uiuc.edu/sigops/roll_your_own/5.a.html

そもそもこのままのソースコードだとコンパイルが通らない。
実際には以下のように*%0としてやる必要があるのだが、本当に同じ意味を保っているか不明確である:

void switch(unsigned int selector)
{
   unsigned int sel[2];
   sel[1] = selector;
   asm ("lcall *%0": :"m" (*sel));    
}

結局この状態で実行するとエミュレータが死ぬ目を見ることになる。

もう一つの方法として、TSSディスクリプタのみを固定し、TSSへのベースアドレスを書き換えながら使う方法である。
こちらのコードはそのような方法で書いてあると思われる:
http://en.skelix.org/skelixos/tutorial06.php

が、このコードだと本当にTSSディスクリプタが1つしかないのだが、どうして1つでタスクスイッチが可能なのか、動作原理がわからない。
TRレジスタに入っているのはセレクタ値なんだから、タスク切り替え前にTSSディスクリプタ上のTSSへのベースアドレスを書き換えてしまい、切り替え前と同じセレクタへ飛んだら切り替え先TSSに現在のレジスタを保存する事になりはしないか??
それともCPUが現在のTSSへのアドレスを保持している?