У меня есть проект, в котором я получаю вектор 32-битных инструкций ARM, и часть инструкций (значения смещения) необходимо читать как числа со знаком (дополнение до двух) вместо чисел без знака.
Я использовал вектор uint32_t
, потому что все коды операций и регистры читаются как беззнаковые, а вся инструкция была 32-битной.
Например:
У меня есть эта 32-битная кодировка инструкций ARM:
uint32_t addr = 0b00110001010111111111111111110110
Последние 19 бит — это смещение ветки, которую мне нужно прочитать как целочисленное смещение ветки со знаком. Эта часть: 1111111111111110110
У меня есть эта функция, в которой параметром является вся 32-битная инструкция: я сдвигаю 13 позиций влево, а затем снова 13 позиций вправо, чтобы иметь только значение смещения и перемещать другую часть инструкции.
Я пробовал приводить эту функцию к разным переменным со знаком, используя разные способы приведения и используя другие функции С++, но она печатает число, поскольку оно было беззнаковым.
int getCat1BrOff(uint32_t inst)
{
uint32_t temp = inst << 13;
uint32_t brOff = temp >> 13;
return (int)brOff;
}
Я получаю десятичное число 524278 вместо -10.
Последний вариант, который я считаю не самым лучшим, но он может сработать, — установить все двоичные значения в строку. Инвертируйте биты и добавьте 1, чтобы преобразовать их, а затем снова преобразуйте новое двоичное число в десятичное. Как я бы сделал это в статье, но это не очень хорошее решение.
temp
иbrOff
должны быть подписаны. Не могу проверить, соответствует ли это стандарту, ноgcc -ansi -pedantic
принимает это :) - person Jester   schedule 17.11.2019u
частьuint32_t
означает без знака. Вот что это значит. Без знака означает: когда вы сдвигаете вправо, старший бит заполняется0
. Это фундаментальное свойство целочисленных типов без знака. Это явно не то, что вам нужно, поэтому вы, очевидно, не можете использовать для этого неподписанный тип. - person Sam Varshavchik   schedule 17.11.2019brOff << 13
потенциально является UB в переносимом C++, потому что вы можете переполнить целочисленный сдвиг влево со знаком. Не выполняйте приведение кint32_t
до после смещения влево. И не публикуйте ответ в вопросе. - person Peter Cordes   schedule 18.11.2019