Тем не менее, библиотека GMP — которую сами по себе используют компиляторы и на которой основана MPFR, которую в свою очередь использует куча калькуляторов www.mpfr.org/#mpfr-sw — для функций нижнего уровня использует ассемблерные версии. Возрастающая сложность поддержки кода для многих архитектур вполне оправдывается возрастающей скоростью.
Среднестатистический код человека-ассемблерщика действительно скорее всего проиграет по скорости коду, который генерирует хороший компилятор с максимальной оптимизацией. Но делать отсюда вывод, что человек в принципе не может, вылизывая небольшой участок, соревноваться с компилятором, несколько странно — как минимум потому, что человек может написать любой код, в том числе идентичный сгенерированному компилятором, а компилятор может сгенерировать не любой код.
Можно ещё сократить, первую и третью — до 24 байт, вторую — до 27 байт.
выходить из COM-программы можно не по int 20h, а по ret; в бинарнике второй программы это даже используется, в отличие от исходника;
int 29h сохраняет ah, так что «mov ah,1» и «int 29h» можно поменять местами, а пару команд «mov al,imm1» и «mov ah,imm2» можно заменить на одну «mov ax,imm2*256+imm1»;
если в мешанину условных переходов закрадывается безусловный, это повод подумать, нельзя ли переупорядочить код, избавляясь от безусловного перехода.
Первая программа:
org 100h
;;Угадай-ка
int 16h ;;Ожидаем нажатие на клавишу
mov bl, al ;;Сохраняем код клавиши в память
still: ;;Главный цикл
int 29h ;;Вывод символа на экран
mov ax, 1*256+13;;al=13 - Возврат каретки, ah=1 - Опрос клавиатуры
int 29h
int 21h
cmp al, bl ;;Сравнение кодов клавиш
mov al, '+'
ja still
mov al, '-'
jb still
true:
ret
Вторая программа:
org 100h
;;Баше
mov dl, 15+4 ;;Поместим в dl количество палочек
still: ;;Главный цикл
sub dl, 4
js fin
mov ax, 1*100h+'|' ;;Выведем символ палочки
mov cl, dl ;;с помощью цикла,
disp: ;;ровно cl раз
int 29h ;;вызвав прерывание 29h
loop disp
int 21h
sub al, '0' ;;Переводим ASCII-код в число
cmp dl, al ;;Забрали последнюю палочку - значит, победили
jne still
win:
int 29h ;;Выведем сердечко
fin:
ret
Третья программа:
;;Однорукий бандит
push 0b800H ;;Обращаемся к видеопамяти
pop ds
le: ;;Вывод символа
inc bx
inc bx ;;Переместим курсор
inf: ;;Почти вечный цикл
int 1AH ;;Вызываем таймер
add dl, bl ;;Мешаем игроку победить, быстро нажимая клавишу "Вправо"
mov [bx], dl ;;Выводим текущий символ на экран
;;Обработчик клавиатуры
in al, 60H
cmp al, 77 ;;Нажата кнопка "Стрелка влево", переходим к следующему символу
jnz inf ;;Почти вечный цикл повторяется почти вечно
re: ;;Пора выводить следующий символ или останавливать бандита
cmp bx, 6
jnz le
ret ;;Конец программы
Среднестатистический код человека-ассемблерщика действительно скорее всего проиграет по скорости коду, который генерирует хороший компилятор с максимальной оптимизацией. Но делать отсюда вывод, что человек в принципе не может, вылизывая небольшой участок, соревноваться с компилятором, несколько странно — как минимум потому, что человек может написать любой код, в том числе идентичный сгенерированному компилятором, а компилятор может сгенерировать не любой код.
Первая программа:
Вторая программа:
Третья программа: