﻿# Распространенная ошибка при компиляции 64\-битного приложения: error C4235, Assembler

Visual C\+\+ не поддерживает 64\-битный встроенный ассемблер\.

В результате вы получите ошибку при попытке компиляции следующего кода:

```cpp
void waitvrt(void)
{
  __asm {
      mov  dx,3dah
  VRT:
      in    al,dx
      test  al,8
      jnz    VRT
  NoVRT:
      in    al,dx
      test  al,8
      jz    NoVRT
  }     
}
1>.\Third_party\Src\CreditsThread.cpp(111) :
error C4235: nonstandard extension used : 
'__asm' keyword not supported on this architecture
```

Если вам все же необходимо использовать ассемблерный код, то можно воспользоваться внешним 64\-битным ассемблером, например, MASM\.

Но скорее всего вам следует переписать данный код на языке Си/Си\+\+\. Высока вероятность, что ассемблерный код уже устарел и рационально использовать современные функции операционной системы или конструкции языка Си/Си\+\+\. Использование ассемблера для оптимизации в настоящее время редко оправдано, так как компилятор Visual C\+\+ в большинстве случаев создаст достаточно эффективный код\. Также не забывайте про возможность использования intrinsic\-функций\.

Intrinsic\-функции \- это специальные системно\-зависимые функции, выполняющие действия, которые невозможно выполнить на уровне Си/Си\+\+ кода или которые выполняют эти действия намного эффективнее\. По сути, они позволяют избавиться от использования inline\-ассемблера, так как его использование часто нежелательно или невозможно\.

Программы могут использовать intrinsic\-функции для создания более быстрого кода за счет отсутствия накладных расходов на вызов обычного вида функций\. При этом, естественно, размер кода будет чуть\-чуть больше\. В MSDN приводится список функций, которые могут быть заменены их intrinsic\-версией\. Это, например, memcpy, strcmp и другие\.

В компиляторе Microsoft Visual C\+\+ есть специальная опция "/Oi", которая позволяет автоматически заменять вызовы некоторых функций на intrinsic\-аналоги\.

Помимо автоматической замены обычных функций на intrinsic\-варианты, можно явно использовать в коде intrinsic\-функции\. Вот для чего это может быть нужно:

* Как уже говорилось, встроенный \(inline\) ассемблерный код не поддерживается компилятором Visual C\+\+ в 64\-битном режиме\. Intrinsic\-код поддерживается\.
* Intrinsic\-функции проще использовать, так как они не требуют знания регистров и других подобных низкоуровневых конструкций\.
* Intrinsic\-функции обновляются в компиляторах\. Ассемблерный же код придется обновлять вручную\.
* Встроенный оптимизатор не работает с ассемблерным кодом, поэтому требуется внешняя линковка модуля\. Для intrinsic\-кода такого не нужно\.
* Intrinsic\-код легче переносить, чем ассемблерный\.

Использование intrinsic\-функций в автоматическом режиме \(с помощью ключа компилятора\) позволяет получить бесплатно несколько процентов прироста производительности, а "ручное" \- даже больше\. Поэтому использование intrinsic\-функций вполне оправдано\.

Более подробно с применением intrinsic\-функций можно ознакомиться в [блоге команды Visual C\+\+](https://devblogs.microsoft.com/cppblog/new-intrinsic-support-in-visual-studio-2008/)\.