gpt4 book ai didi

c - __asm{};返回 eax 的值?

转载 作者:太空狗 更新时间:2023-10-29 15:21:34 24 4
gpt4 key购买 nike

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

最佳答案

__asm__ 本身不返回值。 C 标准未定义 __asm__ 应如何处理返回值,因此编译器之间的行为可能不同。您声明 Visual Studio 示例有效,但 Visual Studio 使用 __asm__asm__ 至少被 GCC 使用。

Visual Studio

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

它避免了存储/重新加载,否则您会从 mov 将值赋给 asm 中的 C 变量并返回该 C 变量,因为 MSVC 内联 asm 语法不支持输入/寄存器中的输出(除了这种返回值的情况)。

Visual Studio 2015 documentation :

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 支持相同的内联 asm 语法,但支持从非 void 函数的末尾掉落作为返回 asm{} block 留在 EAX/RAX 中的值。如果将 MSVC 内联 asm 移植到 clang,请注意这一点。在启用优化(函数内联)的情况下编译时,它会严重崩溃。

海合会

GCC inline assembly HOWTO不包含类似的例子。您不能像在 Visual Studio 中那样使用隐式返回,但幸运的是您不需要这样做,因为 GNU C 内联 asm 语法允许在寄存器中指定输出。不需要 hack 来避免存储/重新加载输出值。

HOWTO 表明您可以将结果存储到汇编 block 内的 C 变量中,并在汇编 block 结束后返回该变量的值。您甚至可以使用 "=r"(var) 让编译器选择它的寄存器选择,以防内联后 EAX 不是最方便的。

(低效的)字符串复制函数的示例,返回 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 语句中保留它。)


如果在启用优化的非 void 函数中省略 return 语句,您会收到类似 warning: no return statement in function returning non -void [-Wreturn-type] 和最近的 GCC/clang 甚至不会发出 ret;它假设这条执行路径从未被采用(因为那将是 UB)。函数是否包含 asm 语句并不重要。

关于c - __asm{};返回 eax 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36802683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com