Доступ к определенному биту во встроенной сборке X86 - PullRequest
1 голос
/ 10 ноября 2010

Я пытаюсь получить доступ к определенному биту и изменить его. Я переместил 0x01ABCDEF (шестнадцатеричное значение) в ecx и хочу иметь возможность проверять битовые значения в определенной позиции. Например, я должен взять байт 0 из 0x01ABCDEF (0xEF) проверьте, равен ли бит в позиции 7 1 установите средние 4 бита на 1, а остальные на 0.

Ответы [ 3 ]

3 голосов
/ 10 ноября 2010

Прошло много лет с тех пор, как я сделал asm, но вы хотите, чтобы ваше значение было 0x80, и если результат равен нулю, ваш бит не установлен, поэтому вы выпрыгиваете, в противном случае продолжайте и установите свой eax на желаемое значение (Я предполагаю, что четыре бита, которые вы имеете в виду, это 00111100 в четвертом байте.

Например (трактуйте это как псевдокод, так как он слишком длинный):

      and eax, 0x80         
      jz  exit
      mov eax, 0x3C
exit: 
2 голосов
/ 10 ноября 2010

В x86 наиболее простым решением является использование инструкций по обработке битов, таких как BT (битовый тест), BTC (битовый тест и дополнение), BTR (битовый тест и сброс) и BTS (битовый тест и установка).

Пример битового теста:

mov      dl, 7      //test 7th bit
bt       ecx, edx   //test 7th bit in register ecx 

Помните: используются только последние 5 бит в регистре edx.

или

bt       ecx, 7

В обоих случаях результат сохраняется внести флаг.

1 голос
/ 10 ноября 2010

Большинство процессоров не поддерживают побитовый доступ, поэтому вы должны использовать ИЛИ для установки и И для очистки битов. Поскольку я не очень знаком со сборкой, я просто дам вам C-ish псевдокод, но вы легко сможете преобразовать его в инструкции по сборке.

value = 0x01ABCDEF;
last_byte = value & 0xFF; // = 0xEF
if (last_byte & 0x40) { // is the 7th bit set? (0x01 = 1st, 0x02 = 2nd, 0x04 = 3rd, 0x08 = 4th, 0x10 = 5th, 0x20 = 6th, 0x40 = 7th, 0x80 = 8th)
    value = value & 0xFFFFFF00; // clear last byte
    value = value | 0x3C; // set the byte with 00111100 bits (0x3C is the hex representation of these bits)
}

Не то чтобы вы могли удалить присвоение last_byte и напрямую проверить value & 0x40. Однако, если вы хотите проверить что-то, что не является наименее значимой частью, вы должны сначала сделать сдвиг. Например, чтобы извлечь ABCD, вы должны использовать следующее:

middle_bytes = (value & 0xFFFF00) >> 8;

value & 0cFFFF00 получает значение более значимых байтов (0x01), а >> 8 сдвигает результат на один байт и, таким образом, избавляется от последнего байта (0xEF).

...