C ++ Y86 дизассемблер - Как интерпретировать .quad - PullRequest
0 голосов
/ 05 февраля 2019

Итак, для назначения класса мы пишем дизассемблер 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 Ответ

0 голосов
/ 05 февраля 2019

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

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

Какая схема здесь мне не хватает?

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

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

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

...