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


Написание функций во встроенной сборке

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

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

; POWER.ASM
; Compute the power of an integer
;
       PUBLIC _power2
_TEXT SEGMENT WORD PUBLIC 'CODE'
_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+4] ; Get first argument
        mov ecx, [ebp+6] ; Get second argument
        shl eax, cl     ; EAX = EAX * ( 2 ^ CL )
        pop ebp         ; Restore EBP
        ret             ; Return with sum in EAX

_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 можно отключить создание этого предупреждения.

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

См. также

Ссылки

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