Floating point 在GCC内联汇编程序中使用浮点

Floating point 在GCC内联汇编程序中使用浮点,floating-point,return-value,inline-assembly,return-value-optimization,Floating Point,Return Value,Inline Assembly,Return Value Optimization,我正在编写一些调试宏,其中一个宏是在返回值未指定给变量时捕获函数的返回值。如果返回值在调试中有用,但在发布版本中不需要,则这可能很有用 以下宏同时适用于整型和指针类型: #define DebugReturn(TYPE,fcn) \ int fcn##_return; \ __asm("movl %%eax,%0":"=mr"(fcn##_return)); \ TYPE fcn##_returned = (TYPE) fcn##_return 例如: static i

我正在编写一些调试宏,其中一个宏是在返回值未指定给变量时捕获函数的返回值。如果返回值在调试中有用,但在发布版本中不需要,则这可能很有用

以下宏同时适用于整型和指针类型:

#define DebugReturn(TYPE,fcn) \
    int fcn##_return; \
    __asm("movl %%eax,%0":"=mr"(fcn##_return)); \
    TYPE fcn##_returned = (TYPE) fcn##_return
例如:

static int Foobar( int &x, int &y )
{
    x = 7;
    y = 8;
    return 9;
}

Foobar( x, y );
DebugReturn( int, Foobar );
DebugTraceFunction( "Foobar( x, y );", x, y, Foobar_returned );
static float FOOBAR( int x, int y )
{
    return 3.14159;
}

FOOBAR( x, y );
DebugReturnFloatingPoint( FOOBAR );
DebugTraceFunction( "FOOBAR( x, y );", x, y, FOOBAR_returned );
将正确显示返回值9

我尝试过以下浮点类型宏的变体,但都不起作用:

#define DebugReturnFloatingPoint(fcn) \
    double register fcn##_return; \
    float fcn##_returned = 2.718281828; \
    __asm("fstl %0":"=m"(fcn##_returned):"t"(fcn##_return))
例如:

static int Foobar( int &x, int &y )
{
    x = 7;
    y = 8;
    return 9;
}

Foobar( x, y );
DebugReturn( int, Foobar );
DebugTraceFunction( "Foobar( x, y );", x, y, Foobar_returned );
static float FOOBAR( int x, int y )
{
    return 3.14159;
}

FOOBAR( x, y );
DebugReturnFloatingPoint( FOOBAR );
DebugTraceFunction( "FOOBAR( x, y );", x, y, FOOBAR_returned );
始终显示返回值3.0056636E+33,而不管FOOBAR实际返回的值是什么。如果我删除行双寄存器fcn###u return;而输入参数“t”(fcn###u return)则始终显示返回值为零。初始值为2.718281828的原因是检查该值是否被汇编指令实际修改。我不关心结果的准确性

当然,我可以很容易地编写float FOOBAR_returned=FOOBAR(x,y),但是使用宏的原因是为了在最终构建中轻松清理代码。在发布版本中,宏将被定义为空字符串,但在最终构建中,我希望完全删除它们,并且不包含任何未引用的局部变量


那么我的浮点指令怎么了?

您检查过-S的输出了吗?我的猜测是,从FOOBAR返回时,gcc总是必须清除浮点堆栈。它要么将其移动到变量中,要么干脆丢弃它。当您到达asm时,该值已经消失。@david我将代码放入一个小程序以测试它:@david我将代码放入一个小程序以测试它,并使用g++testprog.cpp-o testprog构建它,同样的问题也发生了。因此,我使用g++testprog-S构建了它,但它会导致gcc挂起。我试了几次,每次都是20分钟后挂断。输出文件仅包含.file“”什么会导致gcc挂起?g++-S testprog.cpp如何?@david您可能知道,我对gcc比较陌生;我习惯于使用Microsoft Visual Studio。我试过g++-S testprog.cpp,但它挂了12个小时才停止。我做了一些研究,发现我可以使用objdump来获得反汇编,下面是我得到的:调用401190 fstp%st(0)mov 0x4020d4,%eax mov%eax,0x2c(%esp)fldl 0x30(%esp)fstl 0x2c(%esp),这样它会在函数调用后立即弹出堆栈,但是它把值放在哪里呢?你检查过-S的输出了吗?我的猜测是,从FOOBAR返回时,gcc总是必须清除浮点堆栈。它要么将其移动到变量中,要么干脆丢弃它。当您到达asm时,该值已经消失。@david我将代码放入一个小程序以测试它:@david我将代码放入一个小程序以测试它,并使用g++testprog.cpp-o testprog构建它,同样的问题也发生了。因此,我使用g++testprog-S构建了它,但它会导致gcc挂起。我试了几次,每次都是20分钟后挂断。输出文件仅包含.file“”什么会导致gcc挂起?g++-S testprog.cpp如何?@david您可能知道,我对gcc比较陌生;我习惯于使用Microsoft Visual Studio。我试过g++-S testprog.cpp,但它挂了12个小时才停止。我做了一些研究,发现我可以使用objdump来获得反汇编,下面是我得到的:调用401190 fstp%st(0)mov 0x4020d4,%eax mov%eax,0x2c(%esp)fldl 0x30(%esp)fstl 0x2c(%esp),所以它会在函数调用后立即弹出堆栈,但它把值放在哪里?