Mediana.Output

May 25, 2010 02:53


Похоже, вывод дизассемблера следует сделать несколько иначе, чем планировалось. Т.к. каждый хочет выводить результаты на свой лад, необходимо сделать вывод более гибким. Archer предложил сделать вывод с помощью форматирующей строки, но это не очень гибко, т.к. если кому-то приспичит выводить непосредственные операнды, например, в четверичной системе счисления, то мне придется дописывать распознавание спецификатора четверичной системы. Другой вариант -- принимать от пользователя массив обработчиков, в котором каждый обработчик отвечает за вывод элемента инструкции. Обработчики вызываются из Mediana. Это позволит пользователю перегружать ф-ии вывода а ля С++. Подход представляется мне так:
int dump_handler(struct STREAM * const stream, struct INSTRUCTION *instr, int operand, int param1, int param2); int (*handlers)[HANDLERS_NUM](struct STREAM * const, struct INSTRUCTION *, int, int, int); handlers[0] = dump_prefix; handlers[1] = dump_mnemonic; handlers[2] = dump_mnem_op_space; ... medi_dump(..., handlers, ...); Возможные обработчики:
prefix //префикс инструкции. mnem //мнемоника. mnem_op_space //разделитель мнемоники и операндов. op_op_space //разделитель операндов. reg //операнд-регистр. imm //непосредственное значение. dir //операнд-дальний адрес. addr_size //квалификатор размера адреса. addr_open_brace //открывающая скобка операнда-адреса. addr_seg_reg //сегментный регистр адреса. addr_base //базовый регистр адреса. addr_idx //индексный регистр адреса. addr_multiplier //множитель индексного регистра адреса. addr_disp //смещение. addr_base_idx_space //разделитель базового и индексных регистров. addr_idx_multiplier_space //разделитель индексного регистра и множителя. addr_multiplier_disp_space //разделитель множителя и смещения. addr_close_brace //закрывающая скобка. Если в массиве передано значение NULL, то Mediana вызовет обработчик по умолчанию. Кроме того, думаю, стоит добавить возможность вызова обработчика по умолчанию и передачу результатов его работы в пользовательский обработчик. Не уверен, что необходимы обработчики разделителей, разделители можно выводить в обработчиках предшествующего элемента.
Плюс такого подхода: не требуются никакие опции для вывода, достигается максимальная гибкость. Однако есть и минусы:
  • Придется открыть большое число внутренних ф-ий и структур. Например, служебная структура STREAM должна передавться в пользовательский обработчик, но следует строго запретить модификацию этой структуры пользователем. Кроме того придется открыть большое число массивов указателей на строки для удобства написания пользовательских ф-ий вывода.
  • Для вывода результата необходимо использовать только ф-ии вывода значений, определенные в Mediana. (Вероятно, это получится немного упростить, но надо обдумать.) Это связано с тем, что Mediana всегда ведет подсчет выведенных символов и возвращает их пользователю в качестве результата работы ф-ии medi_dump. Это позволяет перезапросить буфер, отведенный под строку вывода, если он слишком мал.
  • Возрастает общая сложность использования дизассемблера, а значит повышается вероятность ошибок.
Буду рад комментариям и предложениям.
Previous post Next post
Up