7

次のGCCインラインasmは、LuaJitのcocoライブラリから取得したものです。誰かがそれが何をするのかを行ごとに説明することができますか?

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");
}

ありがとう

4

2 に答える 2

11

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

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

movl $1f, (%0)

ラベル1(最後の行で定義)のアドレスをパラメーター0(から)に移動します。

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は「コココンテキスト」を意味すると思います。したがって、この関数は現在のスタックフレームを「from」構造に保存し、スタックフレームを「to」構造に保存されているものに設定します。基本的に、現在の関数から別の関数にジャンプします。

于 2009-09-03T06:28:51.070 に答える
2

DevSolarには正しい答えがあります。ここで、EBPとESPの目的についてもう少し学ぶことができることを付け加えておきます

于 2009-09-03T06:43:40.877 に答える