1

これは私が見ている資料です http://hosted.cjmovie.net/TutMultitask.htm

誰かが次のアセンブリコーディングで私を助けてくれれば感謝します

pusha          ;Push all standard registers
push ds        ;Push segment d
push es        ;Push segmetn e
push fs        ; ''
push gs        ; ''

レジスタとセグメントは、プロセスのカーネル レベルのスタックに保存されますが、正しいですか?

mov eax, 0x10  ;Get kernel data segment
mov ds, eax    ;Put it in the data segment registers
mov es, eax
mov fs, eax
mov gs, eax

カーネル データ セグメント記述子をロードする目的は何ですか?

push esp       ;Push pointer to all the stuff we just pushed
call _TaskSwitch ;Call C code

_TaskSwitch を呼び出す前に esp が保存されるのはなぜですか?

ありがとう

4

1 に答える 1

0

コードはコメントでそれを明確に示しています:「プッシュしたばかりのものすべてへのポインターをプッシュする」+「Cコードを呼び出す」、参照TaskSwitch()

//Switch between our two tasks
//Notice how we get the old esp from the ASM code
//It's not a pointer, but we actually get the ESP value
//That way we can save it in our task structure
unsigned int TaskSwitch(unsigned int OldEsp)

したがって、TaskSwitch()スタック上のISRによって保存されたコンテキストのアドレスまたはポインタを(パラメータとして)受け取ります。TaskSwitch()また、スタックに保存されているコンテキストのポインタ/アドレスを返します。受信したものと同じ値を返す場合、切り替えは発生せず、単純な呼び出し+戻りです。別のコンテキストを使用して別のアドレスに返されるため、別のコンテキストを返す場合は切り替えが発生します。

参照しているドキュメントとそこに記述されているコードを読んでください。そこにはすべて非常に明確に書かれています。

于 2012-09-01T05:31:22.063 に答える