Множество команд процессоров 386 создавалось исходя из некоторого опыта
практического программирования. Множество этих практических наблюдений оказалось
полезным для программирования на языке ассемблера процессора i486, и может
оказаться само по себе интересным при создании компиляторов.
· Используйте регистр EAX где только возможно. Многие команды становятся на · один байт короче при использовании регистра EAX, такие, как загрузка в память и · сохранение из памяти при использовании абсолютных адресов, пересылка значений в · другие регистры при помощи команды XCHG, и команды, которые используют · непосредственные значения в качестве операндов. · · Используйте по возможности сегмент D-данных. Команды, работающие с · D-пространством, на один байт короче команд, которые используют другие сегменты · данных по причине отсутствия префикса перекрытия сегмента. · · Придавайте особое значение коротким одно-, двух- и трехбайтным командам. Так · как команды процессора i486 начинаются и заканчиваются на границах байтов, · возможно будет обеспечить такое кодирование команд, которое будет более · компактным по отношению к кодированию для процессоров, использующих множество · команд, выровненных по границам слов. Команда во множестве команд с · выравниванием по словам должна иметь длину в два или четыре байта (или более). · Побайтное выравнивание сокращает размерность кода и увеличивает скорость · выполнения команд. · · Получайте доступ к 16-разрядным данным при помощи команд MOVSX и MOVZX. Эти · команды используют расширение по знаку и расширение по нулю операндов длиной в · слово до длины в двойное слово. Это сокращает необходимость в использовании · дополнительных команд для инициализации старшего слова. · · Для скорейшего отклика на прерывание используйте при возможности прерывание · MNI. · · Вместо использования команды ENTER на лексическом уровне 0, используйте · фрагмент кода, аналогичный следующему : · PUSH EBP· MOV EBP, ESP· SUB ESP, BYTE_COUNT· Этот фрагмент выполняется за семь тактов, а не за десять.
Следующие ухищрения можно применять в качестве оптимизации скорости работы
системы после того, как ее основные команды были реализованы :
· Команды перехода используются в двух основных формах : одна из форм имеет · непосредственное восьмибитовое значение для выполнения относительного перехода в · диапазоне от 128 байт назад до 127 байт вперед, другой формой является полное · 32-разрядное смещение. Многие программисты на ассемблере используют длинную · форму в ситуациях, когда может быть использована короткая форма. Когда · совершенно ясно, что может быть использована короткая форма, явно укажите, что · операнд-приемник имеет размерность в один байт. Это подскажет ассемблеру, что · надо использовать короткую форму. Если ассемблер не поддерживает эту функцию, он · выдаст ошибку. Обратите внимание на то, что некоторые ассемблеры выполняют такую · оптимизацию автоматически. · · Используйте регистр ESP для ссылок на стек на самом глубоком уровне · вложенности подпрограмм. Не беспокойтесь относительно задания значения регистра · EBP и стека данных. · · Для быстрейшего переключения задач используйте программное переключение · задач. Это позволяет запоминать и восстанавливать меньшие по объему данные о · состоянии процессора. Смотри Главу 7 для обсуждения · вопросов многозадачности. · · Используйте команду LEA для сложения регистров. Когда в команде LEA · используются базовый регистр и индексный регистр, в операнд-приемник загружается · их сумма. Содержимое индексного регистра может быть масштабировано кратно 2, 4 · или 8. · · Используйте команду LEA для прибавления константы к регистру. Когда в · команде LEA используются базовый регистр и смещение, сумма загружается в · приемник. Команда LEA может быть использована вместе с базовым регистром, · индексным регистром, фактором масштабирования и смещением. · · Используйте команды перемещения целых для передачи данных формата с · плавающей точкой. · · Используйте форму команды RET с непосредственным значением дла счетчика · байт, а не команду ADD ESP. Это сохраняет при выполнении один тактовый цикл и · три байта на каждый вызов подпрограммы. · · Когда выполняется несколько обращений к переменной, адресуемой со смещением, · загрузите смещение в регистр. · · Команды PUSH и POP, когда используюся вместе с операндом в памяти, · используют на два больше тактов процессора, чем эквивалентная двухкомандная · последовательность, которая передает операнды через регистры общего назначения · перед занесением их в стек и восстановлением из стека. · · Команда LOOP использует при выполнении на два тактовых цикла больше, чем · эквивалентное уменьшение счетчика и команда условного перехода. · · Команда JECXZ использует при выполнении на один тактовый цикл больше, чем · эквивалентное сравнение и команда условного перехода.