2

ビット文字列の一部を抽出して数値を符号拡張しようとして問題が発生しています。これは、負の数の場合に問題があり、正の側に数値を折り返します。これが私のコードです:

//  printf("add1 \n");
unsigned short r1 = (instruction>>6)&7;
signed short amount = (instruction& 31);   //right here! i am trying to get the last 5 bits and store it in a register but i can't figure out how to make it negative if it is negative
//  printf("\namount is %d \n", amount);
unsigned short dest = (instruction>>9)&7;
state->regs[dest] = state->regs[r1]+amount;
setCC(state,state->regs[r1]+amount);
4

5 に答える 5

3

ビット パターンの場合、多くの場合、10 進数ではなく 16 進数の定数を使用する方が簡単です。

signed short amount = (instruction & 0x1F);

次に、数値を符号拡張するには、符号ビットを確認します (ここでの符号ビットは、抽出された 5 ビットの左端であると仮定します)。設定されている場合は、バイナリ反転を実行して 1 を追加します。5 ビット値の 2 の補数を取り (反転して 1 を加算)、次に全幅の結果の 2 の補数を取得します (反転して 1 を加算)。

if (amount & 0x10)
    amount = ~(amount^0x1F + 1) + 1;

例えば。

             5-bit "bitfield"
             X XXXX
0000 0000 0001 1111
0000 0000 0000 0000 invert x ^ 0x1F (= 1 1111)
0000 0000 0000 0001 add 1
1111 1111 1111 1110 invert ~
1111 1111 1111 1111 add 1

0000 0000 0001 0000
0000 0000 0000 1111 invert x ^ 0x1F (= 1 1111)
0000 0000 0001 0000 add 1
1111 1111 1110 1111 invert ~
1111 1111 1111 0000 add 1

おっと。さらに簡単:

-(x^0x1F + 1)  Assuming the machine operates with 2's-complement

0000 0000 0001 0110
0000 0000 0000 1001 invert
0000 0000 0000 1010 add 1 (yielding the full-width absolute value)
1111 1111 1111 0110 negate
于 2013-04-25T17:27:10.597 に答える
2

ビットフィールドを使用します:

union {
      int a;
      struct {
         int a:5;
         int b:3;
         unsigned int c:20;
      } b;
} u = 0xdeadbeef;

int b = u.b.b;  // should sign extend the 3-bit bitfield starting from bit 5
于 2013-04-25T17:33:17.110 に答える
1

Hacker's Delight 2-6 より。符号拡張する必要がある 5 ビットのデータを想定します (符号ビットの値は 16)。

最良のケース: 上位ビットがすべてゼロの場合:

(i ^ 16) - 16

次善のケース (OP の場合と同様instruction): 上位ビットに破棄する必要があるデータが含まれている場合:

(i & 15) - (i & 16)
于 2018-08-08T15:39:05.073 に答える
0

符号ビットを確認し、それに応じて結果を修正できます。

int width_of_field = 5;
signed short amount = (instruction& 31);
if (amount & (1 << width_of_field >> 1)) // look at the sign bit
{
    amount -= 1 << width_of_field; // fix the result
}

または、左シフトに続いて右シフトを使用します。

width_of_field = 5;
signed short amount = (instruction& 31);
// It is possible to omit the "& 31", because of the left shift below
amount <<= 16 - width_of_field;
amount >>= 16 - width_of_field;

int注: (おそらく 32 ビット)への昇格の影響を避けるために、2 つのステートメントを使用する必要があります。

于 2013-04-25T19:28:32.050 に答える