Современная электроника №3/2026
ИНЖЕНЕРНЫЕ РЕШЕНИЯ 20 WWW.CTA.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА • № 3 / 2026 ценное 32-разрядное положительное число 20h. Пример 3 А теперь занесём в этот же регистр большее положительное значение, например, 1020h. Здесь уже потребу- ются обе части: Ch 20 = 1 и Cl 12 = 20h. При разделении числа на составля- ющие учитываем, что 12 бит – это три последние шестнадцатеричные цифры в записи константы. В данном случае для формирования константы потребуются две инструкции. LUI x6, 1; ADDI x6, x6, 20h. Первая определяет старшие биты Ch 20 , а вторая прибавляет к полученному в x6 значению Cl 12 . Полная запись сложения выглядит так: 00001 000 + + 00000 020 = 00001 020. Здесь Ch и Cl для наглядности разделены пробелом. Но, к сожалению, не всегда дело обстоит так просто. Пример 4 Попробуем занести в регистр x6 (можно было бы выбрать и другой) константу 1800h по схеме, предло- женной в предыдущем примере. Полу- чим инструкции LUI x6, 1 и ADDI x6, x6, 800h (специально не оформляем это как кодовый фрагмент, так как он будет работать не совсем правильно). Здесь Ch = 1, а Cl = 800h. Когда процес- сор RISC-V выполнит эти инструкции, то ответ получится не 1800h, как ожи- далось, а всего лишь 800h. Подвох заключается в том, что по принятым правилам будут складываться числа 00001 000 + FFFFF 800 = 00000 800 (у вто- рого слагаемого 800h автоматически расширяется знак – рис. 2). Как это исправить? Обратим вни- мание, что в старших 20 битах после расширения знака Cl вместо нулей устанавливаются единицы. Факти- чески старшая часть операнда име- ет шестнадцатеричное значение FFFFF, т.е. в общепринятом десятич- ном представлении –1. Следователь- но, из Ch неявным образом вычитает- ся 1. Если это заранее предусмотреть и скорректировать Ch , предваритель- но увеличив его на 1, то ответ станет правильным. LUI x6, 2; ADDI x6, x6, 800h. Приведённый скорректированный фрагмент обеспечит занесение в регистр x6 требуемой константы 1800h. Примечание . По нашему мнению, наиболее противоестественно здесь то, что значение исходной константы требуется подменять ради получения правильного итогового результата. Кстати говоря, это не только впечат- ление автора. Так, в [10] не без иро- нии сказано, что обязательное рас- ширение знака непосредственного операнда, принятое в RISC-V, «выгля- дит довольно необычно». Перед нами типичный пример «встречи» про- граммиста и конструктора машины, о которой говорилось выше, причём все выгоды тут явно получил кон- структор. Подчеркнём, что коррекция Ch тре- буется, только когда старший бит Cl (с номером 11) равен 1. В стандар- те [4] можно найти красивую неяв- ную рекомендацию: прибавлять к Ch старший бит Cl (см. описание псев- доопераций на с. 139). Действитель- но, когда старший бит равен 1, кор- рекция Ch будет, а когда он 0 – нет, поскольку прибавление нуля ниче- го не меняет. С теоретической точ- ки зрения выглядит очень изящно, но потребуются дополнительные инструкции выделения бита и его сдвига. Сравните такой алгоритм с принятым в теоретической RISC- модели Д. Кнута [18], где загрузка каждой из частей константы никак не влияла на все остальные биты. Целесообразно также ещё раз вер- нуться к примеру 1 и убедиться, насколько в принятой там ISA зада- ние констант устроено нагляднее и проще. Пример 5 Рассмотрим ещё один выделяю- щийся вариант. Попробуем занести в регистр значение 800h = 2048. Фор- мально следуя описанному в преды- дущем примере алгоритму, немед- ленно получаем работоспособный фрагмент: LUI x6, 1; ADDI x6, x6, 800h. Тем не менее присмотримся к ситуа- ции повнимательнее. Сразу бросается в глаза, что для формирования 12-бит- ной константы с формально нулевым Ch невозможно обойтись без пред- варительной операции LUI . Причём подчеркнём, что речь здесь идёт не об одном значении, а о целом диапазоне чисел от 800h до FFFh (т.е. от 2048 до 4095 в десятичном виде). Ещё более печально, что трудности возникают не только с числами. Как известно, для выделения значений отдельных бит при помощи логической опе- рации AND используются констан- ты-маски, содержащие единствен- ную единицу в нужном бите. Это не какая-то экзотика: подобный приём часто требуется для анализа отдель- ного управляющего бита в регистре состояния внешнего устройства. Так вот, оказывается, что любую подоб- ную маску, кроме 800h, удаётся полу- чить одной инструкцией: биты от 0 до 10 можно установить посредством ADDI , а с 12 по 31 – с помощью LUI . И только для «несчастного» 11-го бита требуется нестандартный вариант из двух инструкций. А чем, собственно, отличается этот бит от всех осталь- ных? Ничем, кроме заложенных в формат инструкций правил! Пример 6 Интересный и важный для практи- ки частный случай имеет место при небольших отрицательных значени- ях. Рассмотрим, следуя [19], значе- ние –1 = FFFFF FFFh. Здесь Ch = FFFFFh и Cl = FFFh. По общей схеме приме- ра 4 получим инструкции LUI x6, 0 и ADDI x6, x6, FFFh. Первая из них явно бесполезна (что, кстати, в [19] не ука- зывается). Несколько подправив вто- рую, получим оптимальное решение ADDI x6, x0, FFFh (напоминаем, что x0 всегда равно 0). Правильные (единичные) значения старших бит будут установлены за счёт расширения знака: здесь оно сыграет положительную роль. Сравнивая данный вариант с при- мером 2, приходим к выводу, что в Таблица. Варианты формирования константы Вариант Пример Значения C Ch 20 Cl 12 Команды Коррекция Ch+1 v1 2 0 ≤ C ≤ 7FF = 0 ≥ 0 ADDI R, x0, Cl Нет, и нет LUI v2 6 F...F800 ≤ C ≤ F…F +1 = 0 < 0 Да, но нет LUI v3 5 800 ≤ C ≤ FFF = 0 < 0 LUI R, Ch+1 ADDI R, R, Cl Да 4 1000 < C < F…F800 ≠ 0 3 ≠ 0 > 0 LUI R, Ch ADDI R, R, Cl Нет v4 7 C = 1000, 2000, … ≠ 0 = 0 LUI R, Ch Нет
RkJQdWJsaXNoZXIy MTQ4NjUy