Как исправить: OP-code считывается некорректно

В настоящее время я пытаюсь написать виртуальную машину Ninja, задача, которая была дана мне в качестве упражнения. Код операции и значение сохраняются в виде 32-битного целого числа без знака, где первые 8 бит являются кодом операции, а остальные — значением. Чтобы справиться с отрицательным значением, я использую макрос, данный мне в упражнении

#define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i))

Однако при попытке получить код операции

unsigned int i = (PUSHC << 24) | SIGN_EXTEND(-2); (где PUSHC равно 1)

с помощью побитового AND, как показано здесь ->

int opcode = (i>>24)&0xff

мой результат — 255, хотя этот метод извлечения работает, когда значение положительное, и в этих случаях воспроизводит правильный код операции.

Исследуя это, я нашел «Как получить значение из непосредственной части 32-битной последовательности в C?», который, по-видимому, имеет дело с тем, что я спрашиваю, однако ответ, данный в этом вопросе, — это именно то, что я делаю, кто-нибудь знает больше?

Этот макрос, похоже, преобразует отрицательные значения 24-bit в 32-bit. Так что SIGN_EXTEND(-2) использует его не по назначению

Eugene Sh. 27.05.2019 22:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

SIGN_EXTEND похоже, что он предназначен для использования в декодировании, чтобы взять 24 бита, которые были извлечены из инструкции, и преобразовать их в 32-битное целое число со знаком. Похоже, он не предназначен для использования в кодировании. Для кодирования IMMEDIATE(x), по-видимому, предназначен для этого. Учитывая 32-битное целое число со знаком, он создает 24-битное целое число со знаком, при условии, что значение подходит.

Так:

unsigned int i = (PUSHC << 24) | SIGN_EXTEND(-2);

должно быть:

unsigned int i = (PUSHC << 24) | IMMEDIATE(-2);

Спасибо, это действительно решило мою проблему. Я пытался заранее изучить, как работают макросы, но, похоже, я еще не совсем в них разобрался. Я был бы признателен, если бы кто-нибудь мог объяснить, что именно происходит, когда вы вводите в них значение. #define IMMEDIATE(x) ((x) & 0x00FFFFFF) и #define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i))

ThatOneGerman 27.05.2019 23:37

Другие вопросы по теме