Задачник "Монитора" В 7-м номере "Монитора" за 1994 год были подведены итоги второй части конкурса, в которой определялась самая короткая подпрограмма, выводящая на экран число в шестнадцатеричном виде. Победителем данного вида многоборья стал Вячеслав Львович Семенов из г.Череповца, предложивший решение объемом 21 байт. Присланное им решение казалось настолько компактным, что даже "старорежимные" программисты отказались от попыток улучшить его. И, как выяснилось, напрасно. В редакцию было прислано решение, превосходящее чемпионский результат на 2 байта, а автором этого решения стал (угадайте с трех раз) 2 Вячеслав Львович  2Семенов! Хотя конкус официально завершен, ознакомиться с этим решением просто необходимо всей программирующей общественности. Чтобы оценить всю его красоту, давайте рассмотрим задачу с самого начала. Итак, нужно написать подпрограмму, которая выводит на экран число в шестнадцатеричном виде, которое передается в регистре AX. Очевидно, что все преобразования числа необходимо проводить в этом же регистре - это не судьба, просто так организована система команд процессоров серии 80x86 и система прерываний DOS (короче int 29h не придумано еще ничего). Все преобразования выполняются в два шага. На первом нибл (группа из четырех битов) помещается в младшие разряды регистра AX, а на втором этот нибл преобразуется, в зависимости от своего значения, либо в цифру, либо в букву. Ну, плюс к тому, еще надо организовать цикл для последовательного перебора всех четырех ниблов, начиная с самого старшего. Как справедливо отметил В. Семенов, "организация цикла Ю. Пером выглядит предпочтительнее", потому что у него наиболее компактно взаимоувязаны две задачи - собственно организация цикла и выделение соответствующего нибла. Show_hex proc near mov cl,12 N_c: push ax shr ax,cl ... int 29h pop ax sub cl,4 jae N_c retn Show_hex endp По-моему, данный фрагмент программы настолько очевиден, что не нуждается в комментариях и полностью совпадает с решеним Ю. Пера ("Монитор" 7'94). Итак, осталась только одна задача - преобразовать значение младшего нибла либо в цифру, либо в букву. Напомню, что в предыдущей версии данной подпрограммы такое преобразование у В. Семенова выглядело следующим образом: aaa jae N_v add al,11h N_v: add al,30h В этом маленьком фрагменте сразу бросаются в глаза две команды сложения, которые выглядят несколько тяжеловесно, и, скорее всего, сэкономить можно именно на их оптимальной организации. Дальше для пояснения решения воспользуюсь письмом В.Семенова. "В основу положено решение системы уравнений: X *Y = 48 mod 256 (X+1)*Y = 65 mod 256 Минимальные значения X и Y, при которых система имеет решение, таковы: X=48, Y=17." Маленькое замечание: 48 - это код символа нуля, а 65 - код символа буквы A. "Имея эти исходные данные и описание команд процессора AAA и AAD, достаточно просто понять процесс преобразования 4 младших битов регистра AX в символьный вид. Команда mov ah,48h подготавливает значение старшего байта для команды символьной коррекции AAD (то есть выполняется присваивание X=48 - Д.П.). Команда aaa модифицирует регистр AL, как описано в "Мониторе" 7'94, но одновременно, если значение 4 младших битов AL было больше 9, то значение AH увеличивается на 1." После выполнения этих двух команд AH=48 и 0=