Что делает эта побитовая операция для эмуляции инструкции RRC

Я работаю над личным проектом, чтобы улучшить мои знания о том, как работает процессор. Поэтому я делаю эмулятор Intel 8080, который представляет собой 8-битный микропроцессор.

В реализации инструкции RRC, примером которой является это:

case 0x0f: {    
  uint8_t x = state->a;    
  state->a = ((x & 1) << 7) | (x >> 1);    
  state->cc.cy = (1 == (x&1));    
}

Я не могу понять, как работает эта линия.

state->a = ((x & 1) << 7) | (x >> 1);

Я знаю, что это должно сдвинуть все биты вправо на 1 позицию, но я не могу понять, как.

Я был бы признателен, если бы кто-нибудь мог дать мне пример того, что он делает шаг за шагом.


  • state->a это uint8_t который эмулирует регистр Intel 8080 с именем A.

  • 0x0f значение HEX для RRC.

  • Пример предоставлен этой страницей.

1 ответ

Решение

Давайте изучим шаги по порядку:

  • uint8_t x = state->a; Используйте временную переменную для текущего значения A регистр;
  • (x & 1) << 7 сдвиньте младший бит на старший бит; (x & 1) значение бита младшего разряда, как и всех других битов x замаскированы.
  • (x >> 1) сдвиньте остальные биты на одно место вправо (по направлению к младшим битам).
  • state->a = ((x & 1) << 7) | (x >> 1); объединить биты из предыдущих 2 шагов и сохранить в качестве нового значения A регистр;
  • state->cc.cy = (1 == (x&1)); сохранить бит младшего разряда из исходного значения в бит переноса (это бит, который был повернут в бит старшего разряда).

Результатом этих шагов является вращение 8 битов на один шаг вправо, причем бит младшего разряда попадает во флаг переноса. Справочная карта 8080 описывает это как Rotate Accumulator Right thru Carry,

Обратите внимание, что шаги могут быть упрощены:

  • state->a = ((x & 1) << 7) | (x >> 1); такой же как state->a = (x << 7) | (x >> 1); так как state->a это uint8_t,
  • state->cc.cy = (1 == (x&1)) такой же как state->cc.cy = x & 1;
Другие вопросы по тегам