C++ Y86 дизассемблер - Как интерпретировать.quad

Итак, для назначения класса мы пишем дизассемблер Y86 (игрушечный процессор) на C++. Достаточно просто, у меня почти все сделано, кроме разборки инструкций в директиву.quad.

Директива quad принимает числовое или шестнадцатеричное значение, а затем преобразует его в 8-байтовую "инструкцию" (на самом деле это не инструкция, .quad - единственная вещь в процессоре, которая занимает 8 байтов, так что если вы встретите 8 байтов) линия, которую вы автоматически знаете, что вы смотрите на четверку), которая представляет значение. Вот пример ниже, так как мое объяснение может быть не очень хорошим:

https://image.prntscr.com/image/h5xAoE4YRryl7HSJ13o5Yg.png

Достаточно легко увидеть, что первые два четырехугольника сдвинуты бит 2 вправо при разборке, но затем следующие два сдвинуты бит 2 влево. Какой шаблон мне здесь не хватает? Вот еще несколько примеров разобранных квадроциклов:

0x0a0: 0300000000000000     | value:            .quad   3
0x0a8:                      | list:
0x0a8: ffffffffffffffff     |                   .quad   -1
0x0b0: 0300000000000000     |                   .quad   3
0x0b8: 0500000000000000     |                   .quad   5
0x0c0: 0900000000000000     |                   .quad   9
0x0c8: 0300000000000000     |                   .quad   3
0x0d0: 2800000000000000     |                   .quad   40
0x0d8: 3000000000000000     |                   .quad   48
0x0e0: fcffffffffffffff     |                   .quad   -4
0x0e8: 0300000000000000     |                   .quad   3
0x0f0: 0700000000000000     |                   .quad   7
0x0f8: 0200000000000000     |                   .quad   2
0x100: 0300000000000000     |                   .quad   3
0x108: f6ffffffffffffff     |                   .quad   -10
0x110: f8ffffffffffffff     |                   .quad   -8

По сути, я пытаюсь написать алгоритм, который будет брать то, что слева на этих скриншотах (собранный код процессора), и возвращает ".quad 0xblahblah", но я не могу понять, что он делает с шестнадцатеричными значениями, чтобы получить их так.

Мой текущий код C++ выглядит следующим образом:

            unsigned int x;
            stringstream oss;
            oss << "0x" << std::uppercase << std::left << std::setw(20) << std::hex << hex;
            string result = oss.str();

            std::istringstream converter(result);
            converter >> std::hex >> x;

Но когда он должен возвращать.quads, которые вы видите на первом скриншоте, который я разместил, он возвращает это:

0x0d000d000d000000    
0xc000c000c0000000    
0x000b000b000b0000    
0x00a000a000a00000   

Каково точное значение собранного машинного кода, когда мне нужно выяснить, что он делает, чтобы в итоге

0x000d000d000d0000    
0x00c000c000c00000    
0x0b000b000b000000    
0xa000a000a0000000  

Как на скриншоте примера.

1 ответ

Решение

Достаточно легко увидеть, что первые два четырехугольника сдвинуты бит 2 вправо при разборке, но затем следующие два сдвинуты бит 2 влево.

Там нет 2-битного сдвига. Существует то, что, если не обращать пристального внимания, это сдвиг в 2 куска (8 бит).

Какой шаблон мне здесь не хватает?

Это не сдвиг битов, это обратный порядок байтов.

Вместо повторяющихся шаблонов, таких как 000A000A000A, попробуйте поэкспериментировать с шаблонами подсчета, такими как 0123456789AB.

И обратите внимание на самое значимое слово, которое 0x0000 почти во всех ваших примерах. Он появляется в конце последовательности байтов, но становится ведущим нулями (даже не напечатанным) в декодере.

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