    включает его. После любой из этих команд, вы можете написать 

    #pragma warn  .rvl 

    для восстановления предыдущего статуса предупреждения. Можно также 
отключить это предупреждение в командной строке с помощью опции, подобной 
-wrvl. Другие комбинации предупреждений (их десятки) документируются в 
справочниках Borland. 
    После оптимизации функции, подобной MySquare(), имеет смысл исследовать 
конечный результат. Для его проверки скомпилируйте еще раз код с опцией -S и 
изучите получившийся ассемблерный код. Новая функция MySquare имеет следующий вид: 

    push bp 
    mov	bp, sp 
    mov	bx, word ptr [bp+4] 
    mov	ax, word ptr [bp+4] 
    imul bx 
    pop	bp 
    ret 

    Сравните этот код с предыдущим неоптимизированным примером. Целый параметр 
пересылается непосредственно в ах, и излишняя инструкция jmp отсутствует. 
Компилятор сам сохраняет, инициализирует и восстанавливает bp. Он также 
добавляет инструкцию ret. 
    Как видно из этого небольшого примера, оптимизация функций требует времени 
и прилежания. Не стоит тратить ваше драгоценное время на оптимизацию кода, 
который уже работает с необходимой скоростью. 

    Выполнение команд переходов 

    Инструкции переходов в ассемблере, такие как, jmp или jnl, приводят к 
продолжению выполнения программы, начиная с заданного адреса. В автономных 
программах TASM места переходов идентифицируются метками. В ВASM инструкции 
перехода asm могут передавать управление только меткам С или C++, подобным 
тем, которые используются оператором goto. В действительности инструкции 
перехода в asm не что иное, как оператор goto. 
    Поскольку адресные метки пишутся на С или C++, они должны существовать 
где-то вне операторов asm. Например, предположим, у вас возникла необходимость 
вставить авторскую подпись в поток кода вместо сегмента данных, где ее могут 
быстрее обнаружить и подделать компьютерные пираты. Вы можете закодировать 
команду перехода, минующую текстовое сообщение, следующим образом: 

    asm { 
        jmp L1
       db 13, 10, ' 1992 by Tom Swan', 0 
    } 
    L1: 
    asm { 
      //... Дополнительные инструкции 
   } 

    Инструкция jmp L1 пропускает директиву db (определение байта), вставляющую 
возврат каретки (13), перевод строки (10) и строку авторской подписи в коде 
(обратите внимание на апострофы и явное завершение строки нулем). Адресная 
метка L1 появляется после начального оператора asm, за ней могут следовать 
операторы С и C++ или еще один оператор asm, как в данном случае. 
    Можно также использовать команды перехода по условию, например jnz, jl и 
др. Если адресные метки не достигаются этими "ближними" инструкциями перехода, 
они аварийно завершают выполнение программы. Например, если вы написали 

    asm jne TARGET, 

    BASM ассемблирует эту инструкцию (перейти, если не равно) неизмененной 
только в том случае, если расстояние от места перехода до TARGET находится в 
диапазоне от -128 до +127 байт. Если адресная метка размещается вне этого 
диапазона, ВASM вставляет команду безусловного перехода в точку входа 
аварийного завершения программы. Эта проблема решается путем преобразования 
условного перехода следующим образом: 

    asm je TEMP 
   asm jmp TARGET TEMP: 

    Идея заключается в пропуске безусловного перехода, если выполняется 
обратное условие. Инструкции jmp и je выполняют совместно те же самые 
действия, что и первоначальный переход jne, однако они "достают" гораздо дальше. 
    ВASM автоматически оптимизирует безусловные инструкции перехода. Если вы напишете 

    asm jmp LABEL 


    446     Часть IV. Разработка приложений 
