Share via


使用内联程序集编写函数

Microsoft 专用

注意

内联程序集仅适用于 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 函数通过其在堆栈上的位置访问其参数。 (请注意,MASM 和一些其他汇编程序中可用的 MODEL 指令还允许按名称访问堆栈参数和局部堆栈变量。)

示例

此程序利用内联程序集代码编写 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 的内联版本不执行 C return 语句,因此它将生成一个无害警告(如果您在警告等级 2 或更高等级进行编译)。 函数将返回一个值,但编译器无法确定缺少 return 语句时是否会返回此值。 可以使用 #pragma warning 来禁止生成此警告。

结束 Microsoft 专用

另请参阅

__asm 块中使用 C 或 C++