3

私は 8 ビット プロセッサで作業しており、C コンパイラでコードを記述しました。現在、140 行以上のコードが 1200 バイトしか使用せず、この 1 行で 200 バイト以上の ROM スペースが使用されています。eeprom_read()は関数です。この 1000 と 100 と 10 の乗算には問題があるはずです。

romAddr = eeprom_read(146)*1000 + eeprom_read(147)*100 +
          eeprom_read(148)*10 + eeprom_read(149);

プロセッサは 8 ビットで、のデータ型はromAddrですint。この行をより最適化された方法で記述する方法はありますか?

4

4 に答える 4

1

乗算を一連の加算にコンパイルできる場合もあります。左シフト演算子を使用して最適化できます。

A*1000 = A*512 + A*256 + A*128 + A*64 + A*32 + A*8

または同じこと:

A<<9 + A<<8 + A<<7 + A<<6 + A<<5 + A<<3

これはまだ単一の「乗算」命令よりもはるかに長いですが、プロセッサには明らかにそれがないため、これが次善の策かもしれません。

于 2013-05-27T14:17:59.780 に答える
1

コンパイラに大きく依存しますが、少なくとも次のように乗算を単純化することをお勧めします。

romAddr = ((eeprom_read(146)*10 + eeprom_read(147))*10 +
          eeprom_read(148))*10 + eeprom_read(149);

これをループに入れることができます:

uint8_t i = 146;
romAddr = eeprom_read(i);
for (i = 147; i < 150; i++)
    romAddr = romAddr * 10 + eeprom_read(i);

コンパイラは、1000 と 100 の乗算を別々に実装する場合と比較して、16 ビット値を 10 で乗算する方がどれほど簡単かを認識するはずです。

ただし、ループを効果的に処理するためにコンパイラに頼ることに完全に満足しているわけではありません。

多分:

uint8_t hi, lo;
hi = (uint8_t)eeprom_read(146) * (uint8_t)10 + (uint8_t)eeprom_read(147);
lo = (uint8_t)eeprom_read(148) * (uint8_t)10 + (uint8_t)eeprom_read(149);
romAddr = hi * (uint8_t)100 + lo;

これらはすべてテストされていません。

于 2013-05-30T18:34:26.003 に答える
1

最もスペースを使用するのは、乗算の使用である可能性があります。プロセッサに乗算を実行する命令がない場合、コンパイラはソフトウェアを使用して段階的に実行する必要があり、かなりの量のコードが必要になる可能性があります。

ターゲットプロセッサ(または使用しているコンパイラ)について何も指定していないため、言うのは難しいです。

1 つの方法としては、インライン化を何とか減らして、10 を掛けるコード (4 つの用語すべてで使用されます) を再利用できるようにすることが考えられます。

これが事実であるかどうかを知るには、マシンコードを検査する必要があります。ところで、アドレス計算に 10 進定数を使用するのは、実に奇妙です。

于 2013-05-27T14:05:55.363 に答える