Немного о выводе инструкций.
За последние пару недель я получил несколько жалоб на то, что вывод инструкций не очень гибкий.
- Невозможность включения/отключения префиксов '0x' и постфиксов 'h' перед и после шестнадцатеричных значений.
- Невозможность управления разделителями между мнемониками и операндами.
- Невозможность включения/отключения вывода сегментных регистров по умолчанию.
- Отсутствие интеллектуального вывода размеров указателей ('byte ptr', 'word ptr', etc), т.е. только в том месте, где возникает неоднозначность.
Несколько соображений по этому поводу:
- В принципе, первые две проблемы решаются с помощью форматирующей строки. Мне эта идея не очень нравится, т.к. требует больших затрат в плане имплементации и абсолютно нерасширяема. Поэтому, думаю, что будет лучше так: в ф-ию вывода dump будут передаваться дополнительные параметры: разделитель между префиксами и мнемоникой, разделитель между мнемоникой и операндами, разделитель между операндами, а также префиксы и постфиксы. Т.е. вызов ф-ии dump теперь будет выглядеть примерно так:
medi_dump(struct INSTRUCTION *instr,
unichar_t *buff,
int bufflen,
int options,
unichar_t *pref_mnem_delimiter,
unichar_t *mnem_ops_delimiter,
unichar_t *ops_delimiter,
unichar_t *disp_prefix,
unichar_t *disp_postfix,
unichar_t *imm_prefix,
unichar_t *imm_postfix);
medi_dump(instr, buff, bufflen, options, _UT(" "), _UT("\t"), _UT(", "), _UT("0"), _UT("h"), _UT("0x"), _UT(""));
Что дает такой вывод:
rep{space}movsb{tab}dword ptr ds:[edi]{, }dword ptr es:[esi]
mov{tab}dword ptr [eax + 0FFFFFFFFh]{, }0xDEADCAFE
Конечно, безобразие в виде одиннадцати параметров никуда не годится, их придется объединить в структуры. Но идея, в целом, ясна, я думаю.
- Включение/отключение вывода сегментных префиксов по умолчанию требует более серьезных изменений. Дело в том, что при выводе инструкции я не знаю, был ли сегментный префикс переопределен или нет. Скорее всего, для этого придется ввести дополнительный флаг операнда, извещающий о том, что префикс инструкции "противоестественнен" и его требуется показать в любом случае.
- Более умный вывод размера указателей, решается довольно простой логикой: если (операнд единственный и является адресом) или (один из операндов является адресом, а другой непосредственным операндом), то { выводим размер указателя }. Конечно, такая логика немного ущербна, особенно для инструкций с тремя операндами, но, ничего другого в голову пока не пришло :).
Хотелось бы услышать мнение, идеи и предложения общественности по поводу вывода.