Как я могу сделать эти операции в C? - PullRequest
2 голосов
/ 04 мая 2010

Я конвертирую некоторый ассемблерный код в C, чтобы иметь возможность использовать его с текущей средой компилятора, с которой мне приходится работать.

Я выполнил 2 операции, я не знаю, как перевести на C. Кто-нибудь знает, как это сделать?

В обоих случаях offset является 32-разрядным целым числом без знака, а shift является целым числом со знаком. C_FLAG - это bool.

OP1:

__asm {
    __asm mov ecx, shift
    __asm ror offset, cl
}

OP2:

__asm {
    __asm bt dword ptr C_FLAG, 0
    __asm rcr offset, 1
}

Большое спасибо за ваш опыт.

P.S .: Я не оригинальный разработчик, и я не видел много кода сборки x86 ...

Ответы [ 5 ]

2 голосов
/ 04 мая 2010

повернуть вправо обсуждение: http://www.osix.net/modules/article/?id=320

графические описания: http://www.penguin.cz/~literakl/intel/r.html

Надеюсь, это поможет

0 голосов
/ 04 мая 2010

При условии, что флаги не используются для хранения постоянного состояния (что является разумным допущением), OP1 эквивалентен:

/* Precondition: `*offset` is in range 0..0xFFFFFFFF */
void inline op1(unsigned long *offset, int shift)
{
    shift = ((unsigned)shift) % 32;

    if (shift)
        *offset = ((*offset >> shift) | (*offset << (32 - shift))) & 0xFFFFFFFFUL;
}

, а OP2 эквивалентен:

/* Precondition: `*offset` is in range 0..0xFFFFFFFF */
void inline op2(unsigned long *offset, unsigned long C_FLAG)
{
    *offset = (*offset >> 1) | ((C_FLAG & 1) << 31);
}

(В 32-битных системах long предварительное условие автоматически выполняется).

0 голосов
/ 04 мая 2010

Хотя это более или менее покрыто, я бы сделал это так:

OP 1: операция поворота вправо в offset, shift местах. В Си это может быть примерно так:

offset = (offset >> shift) | (offset << (WORD_LENGTH - shift);

Вы можете получить длину слова, например, с sizeof(void *) * 8.


ОП 2: Я думаю, что эта операция реализует операцию RRX в сборке x86. Это еще один тип операции поворота вправо, где флаг переноса используется для обеспечения сдвига 33-битной величины. В Си это может быть что-то вроде этого:

offset = (C_FLAG << 31) | (offset >> 1);

Где C_FLAG - флаг переноса, вы должны узнать больше о том, для чего действительно используется значение bool в вашем коде.

0 голосов
/ 04 мая 2010

для второго оп

__asm bt dword ptr C_FLAG, 0

устанавливает флаг переноса бита в C_FLAG (так 1 или 0)

__asm rcr offset, 1

- поворот поворота влево, который является 33-битным поворотом с использованием флага переноса в качестве 33-го бита (и результаты помещают 33-й бит в флаг переноса. Что (я думаю) такое же, как

offset =  offset << 1 + C_FLAG ? 1:0

(если вы не заботитесь о флаге переноса позже)

РЕДАКТИРОВАТЬ - по какой-то причине я читал rcr как rcl. Так что больше похоже на

offset = offset >> 1 | (C_FLAG ? 1<<31 : 0)
0 голосов
/ 04 мая 2010

Для сдвига битов, как в первом примере, используйте оператор <<. В языке C не существует обтекания для смен, часто называемого вращением . Вы должны выполнить операцию самостоятельно:

unsigned char carry;
carry = byte & 0x80; // Save the Most Significant bit for 8-bit byte.
byte <<= 1;  // Left shift by one, insert a 0 as the least significant bit.
byte |= carry;  // Put the rotated bit back into the byte.

Некоторые процессоры также имеют операцию поворота через перенос , которая будет вращать значение переноса в следующую смену. Это предполагает, что carry будет глобальной переменной.

Для проверки битов на языке C вы будете использовать & (двоичный оператор AND) и, возможно, оператор ~ (отрицание). Чтобы проверить самый старший бит в 8-битном байте:

   if (byte & 0x80)
   {
      // bit is a 1
   }
   else
   {
      // bit is a 0
   }

После всего сказанного вам необходимо выяснить, почему используется флаг carry (C_FLAG), и разработать вокруг него другую систему. Как правило, бит переноса недопустим вне функции ассемблера, в которой он используется. Некоторые тесно связанные функции ассемблера могут нарушать это правило. В этом случае переписайте язык ассемблера, а не отлаживайте его. Редизайн всей программы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...