Поделиться через


Создание функций с помощью встроенного языка ассемблера

Блок, относящийся только к системам Майкрософт

Примечание.

Встроенная сборка доступна только для целевых объектов x86. Для аналогичных функций в коде x64 или ARM64 используйте встроенные компоненты компилятора.

Если при создании функции используется встроенный код ассемблера, можно легко передать аргументы в функцию и вернуть из нее значение. В следующих примерах сравнивается функция, написанная для отдельного сборщика, и функция, перезаписанная для встроенного кода на языке ассемблера. Функция power2 получает два параметра путем умножения первого параметра на 2 в степени второго параметра. Как отдельный файл сборщика функция может выглядеть следующим образом:

; power2.asm 
; x86 code for C interop
; Command line: ml /c /Cx /W3 /WX power2.asm 
        .686P
        .XMM
        .MODEL  flat

PUBLIC  _power2
; int power2(int num, int power);
; computes num x 2^power
_TEXT   SEGMENT
_power2 PROC
        push    ebp             ; save EBP
        mov     ebp, esp        ; Move ESP into EBP so we can refer
                                ;   to arguments on the stack
        mov     eax, [ebp+8]    ; load first argument
        mov     ecx, [ebp+12]   ; load second argument
        shl     eax, cl         ; compute result in EAX
        pop     ebp             ; restore EBP
        ret
_power2 ENDP
_TEXT   ENDS
END

Так как он записывается как отдельный файл сборщика, функция требует отдельных этапов сборки и связывания. Аргументы функций C и C++ обычно передаются в стек, поэтому эта версия функции power2 обращается к аргументам по их позициям в стеке. (Директива MODEL , доступная в MASM и некоторых других сборщиках, также позволяет получить доступ к аргументам стека и локальным переменным стека по имени.)

Пример

В следующей программе функция power2 написана со встроенным кодом на языке ассемблера.

// Power2_inline_asm.c
// compile with: /EHsc
// processor: x86

#include <stdio.h>

int power2( int num, int power );

int main( void )
{
    printf_s( "3 times 2 to the power of 5 is %d\n", \
              power2( 3, 5) );
}
int power2( int num, int power )
{
   __asm
   {
      mov eax, num    ; Get first argument
      mov ecx, power  ; Get second argument
      shl eax, cl     ; EAX = EAX * ( 2 to the power of CL )
   }
   // Return with result in EAX
}

Встроенная версия функции power2 ссылается на аргументы по имени и отображается в том же исходном файле, что и остальные части программы. Кроме того, для этой версии требуется меньше инструкций сборки.

Поскольку встроенная версия функции power2 не выполняет оператор return С, при компилировании на уровне предупреждений 2 или выше отображается безвредное предупреждение. Функция возвращает значение, но компилятор не может сказать, что он делает в отсутствие инструкции return . Вы можете отключить #pragma warning создание этого предупреждения.

Завершение блока, относящегося только к системам Майкрософт

См. также

Использование C или C++ в __asm блоках