是否__asm {};返回eax的值? [英] Does __asm{}; return the value of eax?

查看:187
本文介绍了是否__asm {};返回eax的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简单的问题. C语言中的函数asm用于在代码中进行内联汇编.但是它返回什么呢?是常规的eax,如果不是,返回什么?

Simple question. The function asm in C is used to do inline assembly in your code. But what does it return? Is it the conventional eax, and if not, what does it return?

推荐答案

__asm__本身不返回值. C标准没有定义__asm__应该如何处理返回值,因此,编译器之间的行为可能有所不同.您说Visual Studio示例有效,但是Visual Studio使用__asm. __asm__至少由GCC使用.

__asm__ itself does not return a value. C standard does not define how __asm__ should handle the return value, so the behavior might be different between compilers. You stated that Visual Studio example is valid, but Visual Studio uses __asm. __asm__ is used at least by GCC.

要在C程序中获取结果,可以将返回值放在汇编代码中的eax中,然后从函数中返回.调用方将接收eax的内容作为返回值.即使启用了优化,即使编译器决定内联包含__asm{}块的函数,也支持此功能.

To get the result in a C program, you can place return value to eax in the assembly code, and return from the function. The caller will receive contents of eax as the return value. This is supported even with optimization enabled, even if the compiler decides to inline the function containing the __asm{} block.

它避免了存储/重载,否则会从mov将值存储到asm中的C变量并返回该C变量,因为MSVC嵌入式asm语法不支持寄存器中的输入/输出(除非对于这种返回值的情况).

It avoids a store/reload you'd otherwise get from moving the value to a C variable in the asm and returning that C variable, because MSVC inline asm syntax doesn't support inputs/outputs in registers (except for this return-value case).

Visual Studio 2015文档:

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
   // by falling off the end of a non-void function
}

clang -fasm-blocks支持相同的inline-asm语法,但不支持退出非void函数的结尾,因为返回的值是EAX中剩余的asm{}块的值/RAX.请注意,如果将MSVC内联asm移植到clang.在启用优化功能(函数内联)的情况下进行编译时,它将导致严重破坏.

clang -fasm-blocks supports the same inline-asm syntax but does not support falling off the end of a non-void function as returning the value that an asm{} block left in EAX/RAX. Beware of that if porting MSVC inline asm to clang. It will break horribly when compiled with optimization enabled (function inlining).

GCC内联汇编HOWTO 不包含一个类似的例子.您不能像在Visual Studio中那样使用隐式返回,但是幸运的是您不需要这样做,因为GNU C内联asm语法允许在寄存器中指定输出.无需修改即可避免存储/重载输出值.

GCC inline assembly HOWTO does not contain a similar example. You can't use an implicit return as in Visual Studio, but fortunately you don't need to because GNU C inline asm syntax allows specifying outputs in registers. No hack is needed to avoid a store/reload of an output value.

HOWTO显示您可以将结果存储到汇编块内的C变量中,并在汇编块结束后返回该变量的值.您甚至可以使用"=r"(var)让编译器选择其寄存器选择,以防内联后EAX并非最方便.

The HOWTO shows that you can store the result to C variable inside the assembly block, and return value of that variable after the assembly block has ended. You can even use "=r"(var) to let the compiler pick its choice of register, in case EAX isn't the most convenient after inlining.

(低效)字符串复制函数的示例,返回值dest:

An example of an (inefficient) string copy function, returning value of dest:

static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__(  "1:\tlodsb\n\t"
                       "stosb\n\t"
                       "testb %%al,%%al\n\t"
                       "jne 1b"
                     : "=&S" (d0), "=&D" (d1), "=&a" (d2)
                     : "0" (src),"1" (dest) 
                     : "memory");
return dest;
}

(请注意,dest实际上不是内联asm语句的输出.虚拟输出操作数的匹配约束告诉编译器内联asm破坏了该变量的副本,因此它需要在asm中保留它声明.)

(Note that dest isn't actually an output from the inline asm statement. The matching constraint for the dummy output operands tells the compiler the inline asm destroyed that copy of the variable so it needs to preserve it across the asm statement on its own somehow.)

如果在启用优化功能的非void函数中省略了return语句,则会收到类似warning: no return statement in function returning non-void [-Wreturn-type]的警告,并且最近的GCC/clang甚至不会发出ret;它假定此执行路径永远不会被采用(因为它将是UB).函数是否包含asm语句无关紧要.

If you omit a return statement in a non-void function with optimization enabled, you get a warning like warning: no return statement in function returning non-void [-Wreturn-type] and recent GCC/clang won't even emit a ret; it assumes this path of execution is never taken (because that would be UB). It doesn't matter whether or not the function contained an asm statement or not.

这篇关于是否__asm {};返回eax的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆