2009-09-03 9 views
6

次のGCCインラインasmは、LuaJitのcocoライブラリから取得したものです。誰かがそれが何をしているのかという行ごとの説明を提供できますか?Asmコードの説明

static inline void coco_switch(coco_ctx from, coco_ctx to) 
{ 
    __asm__ __volatile__ (
    "movl $1f, (%0)\n\t" 
    "movl %%esp, 4(%0)\n\t" 
    "movl %%ebp, 8(%0)\n\t" 
    "movl 8(%1), %%ebp\n\t" 
    "movl 4(%1), %%esp\n\t" 
    "jmp *(%1)\n" "1:\n" 
    : "+S" (from), "+D" (to) : : "eax", "ebx", "ecx", "edx", "memory", "cc"); 
} 

おかげ

答えて

10

私のASMは詳細について少しあいまいですが、私は、私はあなたの一般的なアイデアを与えることができると思います。

ESP:スタックポインタ、EBP:ベースポインタ。

movl $1f, (%0) 

値0x1fをパラメータ0(from)に移動します。

movl %%esp, 4(%0) 

レジスタESPの内容を(+ 4から)に移動します。

movl %%ebp, 8(%0) 

レジスタEBPの内容を(+ 8)に移動します。

movl 8(%1), %%ebp 

(+8)の内容をEBPに移動します。

movl 4(%1), %%esp 

(〜+ 4)の内容をレジスタESPに移動します。

jmp *(%1) 

(to)に含まれるアドレスにジャンプします。

「1:」はジャンプラベルです。

"+ S"は "ソース"(読み取り)パラメータを宣言し、 "+ D"は宛先(書き込み)パラメータを宣言します。ステートメントの最後にあるレジスタのリストは、 "clobber"リストであり、ASMコードによって変更される可能性のあるレジスタのリストなので、コンパイラは一貫性を維持するためのステップを踏むことができます(つまり、ECXに依然として同じ値従来通り)。

私は、coco_ctxは "cocoコンテキスト"を意味すると思います。 So:この関数は、現在のスタックフレームを「from」構造体に保存し、スタックフレームを「to」構造体に保存されているものに設定します。基本的には、現在の関数から別の関数にジャンプします。

+2

のためのものであるかについてもう少し学ぶことができることを追加します。しかし、ある関数から別の関数にジャンプするだけではありません。呼び出しスタック全体から別の呼び出しスタックにジャンプしています。実行コンテキストを完全に切り替えています。 (また、GCCのインラインアセンブリ構文は奇妙です。) – Crashworks

+2

Cの関数呼び出しのような構文でラップされたAT&Tの構文(http://wiki.osdev.org/Opcode_syntax)です(http://wiki.osdev.org/Inline_Assembly)。あなたはそれを信じませんが、私は実際には "標準的な"インテルの構文よりも好きです。 ;-) – DevSolar

+0

コンテキストスイッチはC++でも動作しますか?またはこのコールのために別のものを書く必要がありますか? – jameszhao00

2

DevSolarは、正しい答えを持っている - 私はちょうどあなたがEBPとESPはまさにそうですhere.