2016-05-30 2 views
7

には何を立つん、私はインラインアセンブラコードの一部が見つかりました:は、%Pは、Linuxカーネル<code>linux/arch/x86/boot/main.c</code>ではgccのインラインアセンブリ

asm("leal %P1(%%esp),%0" 
     : "=r" (stack_end) : "i" (-STACK_SIZE)); 

このコードスニペットは非常に単純ですが、%P1は私を混乱しました。私はアセンブリ言語のチュートリアルを調べましたが、これについては何も見つかりませんでした。

だから誰も私にこのことについての手がかりを与えることができますか?

+1

が私を引用しないでください、私は 'P'サイズのオペランドプレフィックスはすぐに値をとると' $ 'を取り除き_GCC_の一部のバージョンで信じていますその値をx86変位値に使用できるようにします。 '%1'を使ったばかりの場合、出力は' leal $ stackdisp(%esp) 'のようになります。 (ここで、stackdispはオペランド1の値でした)。 '$'が出された場合、アセンブラはそれに不満を持ちます。 –

+1

Linuxカーネルの "m"に対して修飾子 "P"と制約 "p"を使用した[gccインラインアセンブリ]の重複の可能性があります(http://stackoverflow.com/questions/20965114/gcc-inline-assembly-using-modifier-p -and-constraint-p-over-m-in-linux-kern) –

+2

混乱の一部は、 'P'修飾子が文書化されていないことに疑いはありません。一般的に@MichaelPetchにはこの権利があります:gccが@PLTやBYTE PTRのように%1に適用されてしまうかもしれない「装飾」を無効にします(https:// gccの「P」を自由にスキャンしてください)。 gnu.org/viewcvs/gcc/trunk/gcc/config/i386/i386.c)。 "i"という制約が与えられていると、これは(文書化された!) '%c1'修飾子を使って書かれると本当に思いますが、ここに歴史があるかもしれません。 –

答えて

3

P出力修飾子が非公式gcc/config/i386/i386.md内のコメントに記載されています:

;; The special asm out single letter directives following a '%' are: 
... 
;; P -- if PIC, print an @PLT suffix. 
;; p -- print raw symbol name. 

大文字P修飾子は、おそらくここに望まれるものではありませんが、PIC(位置独立コード)をコンパイルしていないとき、小文字のp修飾子のように動作します。コンパイラが即値に通常使用される形式を使用してオペランドを出力するのを防ぐためのもので、ここでは動作しません。 David Wohlferdは、documentedの修飾子cを使用することをお勧めします。具体的には即値を扱うことを意図しています。 c修飾子が文書化される前にこのコードが書かれている可能性があることを覚えておいてください。長い間、修飾語は文書化されていませんでした。

インラインアセンブリステートメントは起動時に1回だけ実行されるため、パフォーマンスは問題にならないため、LEAを使用することで賢明にしようとは心配しませんでした。あなたは完全にのような単純なもので、オペランドの修飾子を避けることができます。

char *stack_pointer; 
asm ("mov %%esp, %0" : "=r" (stack_pointer)); 
stack_end = stack_pointer - STACK_SIZE; 
関連する問題