私は関数をcからアセンブリに書き直そうとしています。これは、これをより効率的にするのではなく、Cでアセンブリを書くことの練習です。トラブルCのASMブロックを結合する
問題は、私は3つのasm()ブロックで作業していますが、それらを組み合わせることはできません。私はそれらを組み合わせるときに私が紛失しているものがなければならないと思う。
これは、現在動作するコードです:
コードの仕事の上の部分の両方が期待通り:
137 __asm__ __volatile__ (
138 "mov R0, #1\n\t"
139 "mov R1, %[bb]\n\t"
140 "and R0, R1\n\t"
141 "cmp R0, #1\n\t" // (b & 1) == 1
142 "bne aftereor\n\t"
143 "eor %[pp], %[pp], %[aa]\n\t"
144 "aftereor:\n\t"
145 "mov %[hbs], %[aa]\n\t"
146 "mov R0, #128 \n\t"
147 "and %[hbs], R0 \n\t"
148 "lsl %[aa], %[aa], #1\n\t"
149 : [pp]"+l" (p),[aa]"+l" (a),[hbs]"=l" (hi_bit_set)
150 : [bb]"l" (b)
151 :
152 );
153 __asm__ __volatile__ (
154 "cmp %[hbs], #128 \n\t"
155 "bne brancha \n\t"
156 "mov R2, #0x1b\n\t"
157 "eor %[aa], %[aa], R2\n\t"
158 "brancha:\n\t"
159 : [aa]"+l" (a)
160 : [hbs]"l" (hi_bit_set)
161 :
162 );
163 __asm__ __volatile__ (
164 "lsr %[bb], %[bb], #1"
165 : [bb]"+l" (b)
166 :
167 :
168 );
これは私がアセンブリに書き換えしようとしていますCコードです。しかし、私の問題は、アセンブリの3つのブロックを1つにまとめるときです。たとえば、次のコードは何らかの理由で期待どおりに動作しません。
137 __asm__ __volatile__ (
138 "mov R0, #1\n\t"
139 "mov R1, %[bb]\n\t"
140 "and R0, R1\n\t"
141 "cmp R0, #1\n\t" // (b & 1) == 1
142 "bne aftereor\n\t"
143 "eor %[pp], %[pp], %[aa]\n\t"
144 "aftereor:\n\t"
145 "mov %[hbs], %[aa]\n\t"
146 "mov R0, #128 \n\t"
147 "and %[hbs], R0 \n\t"
148 "lsl %[aa], %[aa], #1\n\t"
149 "cmp %[hbs], #128 \n\t"
150 "bne brancha \n\t"
151 "mov R2, #0x1b\n\t"
152 "eor %[aa], %[aa], R2\n\t"
153 "brancha:\n\t"
154 "lsr %[bb], %[bb], #1"
155 : [pp]"+l" (p),[aa]"+l" (a),[hbs]"+l" (hi_bit_set),[bb]"+l" (b)
156 :
157 :
158 );
Iが行われた変更のみが読み取りおよび書き込みする両方の変数「hi_bit_set」と「B」を変更、最初に2番目と3番目のブロックを結合しました。私の理解には、これは私にとってはうまくいくようです。しかし、これは正しい結果を生んでいないので、私は何かを見逃していると推測しています。
ご協力いただきありがとうございます。
お返事ありがとうございます。私は今clobbersを理解する、私はちょうどそのビットを逃したと思う。 答えの2番目の部分については、私は16ビットのサム命令に限定されているので、あなたが提案した条件付き実行の最適化はできません。 –
さらに、 "r0"、 "r1"、 "r2" "をクローバーリストに追加すると、コードを実行する前に" r0 "、" r1 "、" r2 "の値を他のレジスタに移動させるように見えます。コンパイラに特定のレジスタの代わりにレジスタを使用するよう指示する方法はありませんか?確かにこれは、コードブロックの前後でレジスタを移動する必要がないので、より効率的です。 –
親指の指示がある[こちらはコードです](https://godbolt.org/g/Nkv02f)メインコードは9命令です。 16ビットのサムコード。コンパイラが動かないようにする方法があります。たとえば、tmp1、tmp2、tmp3を入出力としてリストし、レジスタの名前を付けません。しかし、サムはビットのステータスを取得するのに 'lsls'を使うことができるので、レジスタに定数をロードする必要はありません。そのため、すべてのtmpX値を持っています。 –