質問

なんだろうけど、日本人があまりなく、以下のアセンブラの警告?

コードはx86、32ビット:

int test (int x)
{
  int y;
  // do a bit-rotate by 8 on the lower word. leave upper word intact.
  asm ("rorw $8, %0\n\t": "=q"(y) :"0"(x));
  return y;
}

まコンパイルで取得し、以下の(非常に有効な警告:

Warning: using `%ax' instead of `%eax' due to `w' suffix

私が求めていたものであるかのコンパイラ/アセンブラといアクセスの下位16ビット-サブレ%0になります。アクセスはバイトサブレジスタ(この場合においてAL AH)思います。

しかし、私は、"q"のマー改質剤、そのコンパイラの使用を強制されEAX,EBX,ECXはEDX.また、コンパイラに取りに登録するサブレジスタ.

私能力のasm-コード使用特定の登録(とそのサブレジスタ)ですが、たいへの登録-配分の仕事のコンパイラです。

役に立ちましたか?

解決

利用できる %w0 またのを覚えています。だけを試験することもできます。:-)

int
test(int x)
{
    int y;
    asm ("rorw $8, %w0" : "=q" (y) : "0" (x));
    return y;
}

編集:のOPできない、以下のもの:

int
test(int x)
{
    int y;
    asm ("xchg %b0, %h0" : "=Q" (y) : "0" (x));
    return y;
}

現在の場所にしたんで文書化されては gcc/config/i386/i386.md, いずれの基準書です。

他のヒント

昔、私はずれることを自分の将来の参考...

の追加をクの答えは、キーを使用していますので、修飾子との間に'%'の出力のオペランド.例えば、 "MOV %1, %0" なること "MOV %q1, %w0".

見られませんでしたが何か。md、 /gcc/config/i386/i386.c この潜在的に有用なコメントのソース print_reg():

/* Print the name of register X to FILE based on its machine mode and number.
   If CODE is 'w', pretend the mode is HImode.
   If CODE is 'b', pretend the mode is QImode.
   If CODE is 'k', pretend the mode is SImode.
   If CODE is 'q', pretend the mode is DImode.
   If CODE is 'x', pretend the mode is V4SFmode.
   If CODE is 't', pretend the mode is V8SFmode.
   If CODE is 'h', pretend the reg is the 'high' byte register.
   If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
   If CODE is 'd', duplicate the operand for AVX instruction.
 */

コメントは以下 ix86_print_operand() ご提供の例:

b--印刷のQImode名の登録に記載のオペランド.

%b0い印刷%alの場合オペランド[0]は日0になります。

数用のオプションの下に表示され 出力テンプレートGCC Internals ドキュメンテーション

'%cdigit'に使用できる代替える演算子は一定の 値の書式が正常に表示即時にオペランド.

'%ndigit'は'%cdigit'の値の定数 否定され、その反省に基づいようにお願いいたします。

'%adigit'に使用できる代理演算子またはメモリ 参考に、実際のオペランドとして扱われのアドレスです。これを可能に 有を出力する場合は、"ロードアドレスは"指導で多くの アセンブラの構文は、その指示する必要があるの オペランドとしてこれまでのメモリを参考にした。

'%ldigit'が使用されている代用するlabel_refへジャンプする

'%='出力の数値は各指導に係る職務遂行に 全体を作成する。このため地元のラベルを貼付 れたときのシングルテンプレートを生成する 複数のアセンブラに示します。

%c2'の構築を容易に適切な形式、LEAの指示をオフセット:

#define ASM_LEA_ADD_BYTES(ptr, bytes)                            \
    __asm volatile("lea %c1(%0), %0" :                           \
                   /* reads/writes %0 */  "+r" (ptr) :           \
                   /* reads */ "i" (bytes));

注意を要が薄れ'c'に'%c1'.このマクロに相当

ptr = (char *)ptr + bytes

的な利用、通常の整数演算実行のポートがあります。

編集追加:

直接電話にx64できるので難しいが必要になるので他の非正規滞在の修飾:'%P0 れるようにするための日替)

#define ASM_CALL_FUNC(func)                                         \
    __asm volatile("call %P0") :                                    \
              /* no writes */ :                                     \
              /* reads %0 */ "i" (func))                           

低い場合は"p"の修飾といった機能も同じでGCCが、資本'P'は認められました。詳しくはあり /gcc/config/i386/i386.c.検索"'p'".

なんでもらえるように考えていく---あきスペースに"q"のマークの制約を資本金"Q"における拘束条件クリスの第二ソリューション:

int
test(int x)
{
    int y;
    asm ("xchg %b0, %h0" : "=Q" (y) : "0" (x));
    return y;
}

"q"と"Q"に若干の違いがあり64ビットモードが取得できな最低のバイトの整数レジスタ(ax-bx、cx、dx、si、sp、bp、r8-r15).もののみを取得することができますので最低のバイトなどah)のジ386レジスタ(ax bx,cx,dx).

ながさらにお得な価格でのんこ---は少ないのではないでしょうかも効率的です。32ビットのx86プロセッサは、一般的に 遅い で操作する16ビットのデータは、一般登録するすべきであるベンチマークした場合の性能が重要になります。

ない場合は(a)、パフォーマンスが重視される、(b)と組み合わせることはなく、保存自分のメンテナンスの手間というテーマC:

uint32_t y, hi=(x&~0xffff), lo=(x&0xffff);
y = hi + (((lo >> 8) + (lo << 8))&0xffff);

GCC4.2-O2こが最適な金利が上昇するのが指示...

Gotcha.どの場合はプリミティブルーチンにいることを再利用する、いうことは---この登録は、ネーミングトリックするクリスを指摘するもとって、覚えておいてください。

れていただければと思いますので、標準GCC docs!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top