GCC使用asm块错误地内联函数

时间:2022-10-31 15:13:42

In the process of porting code from Watcom to GCC I noticed incorrectly generated function, and couldn't figure out why it happens. Here is minimal example:

在将代码从Watcom移植到GCC的过程中,我注意到错误生成的函数,并且无法弄清楚它为什么会发生。这是最小的例子:

#include <stdio.h>

bool InstallExceptionHandler(int exceptionNo, void (*handler)())
{
    bool result;
    asm volatile (
        "mov  ax, 0x203     \n"
        "mov  cx, cs        \n"
        "int  0x31          \n"
        "sbb  eax, eax      \n"
        "not  eax           \n"
        : "=eax" (result)
        : "ebx" (exceptionNo), "edx" (handler)
        : "cc", "cx"
    );
    return result;
}

void Exception13Handler(){}

main()
{
    if (!InstallExceptionHandler(13, Exception13Handler)) {
        printf("Success!");
        return 0;
    } else {
        printf("Failure.");
        return 1;
    }
}

At line 63 function InstallExceptionHandler() is inlined, but all that remains of it is asm block. Code to set up input registers edx and ebx is missing. If function is given __attribute__((noinline)) and actual call is emitted, correct code is generated. Is this some bug in the compiler or my code is not valid?

在第63行,函数InstallExceptionHandler()被内联,但剩下的就是asm块。缺少设置输入寄存器edx和ebx的代码。如果函数被赋予__attribute __((noinline))并且发出实际调用,则生成正确的代码。这是编译器中的一些错误还是我的代码无效?

48                      .globl  _main
50                  _main:
51                  LFB15:
52                      .cfi_startproc
53 0000 55              push    ebp
54                      .cfi_def_cfa_offset 8
55                      .cfi_offset 5, -8
56 0001 89E5            mov ebp, esp
57                      .cfi_def_cfa_register 5
58 0003 83E4F0          and esp, -16
59 0006 83EC10          sub esp, 16
60 0009 E8000000        call    ___main
60      00
61                  /APP
62                   # 15 "b.cpp" 1
63 000e 66B80302        mov  ax, 0x203     
64 0012 668CC9      mov  cx, cs        
65 0015 CD31        int  0x31          
66 0017 19C0        sbb  eax, eax      
67 0019 F7D0        not  eax      

Command line: gcc -O3 -m32 -masm=intel -Wa,-adhlns=b.lst b.cpp, gcc -v output: Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=f:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe Target: mingw32 Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --ena ble-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32 -registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gm p-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-sy stem-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv -prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIM E_T Thread model: win32 gcc version 4.8.1 (GCC)

命令行:gcc -O3 -m32 -masm = intel -Wa,-adhlns = b.lst b.cpp,gcc -v output:使用内置规范。 COLLECT_GCC = g ++ COLLECT_LTO_WRAPPER = f:/ mingw / bin /../ libexec / gcc / mingw32 / 4.8.1 / lto-wrapper.exe目标:mingw32配置:../ gcc-4.8.1 / configure --prefix = / mingw --host = mingw32 --build = mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable -lto --enable-libssp --disable-multilib - -ena ble-languages = c,c ++,fortran,objc,obj-c ++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32 -registry --enable-libstdcxx-debug --enable-version -specific-runtime-libs --with-gmp = / usr / src / pkg / gm p-5.1.2-1-mingw32-src / bld --with-mpc = / usr / src / pkg / mpc-1.0。 1-1-mingw32-src / bld --with-mpfr = --with-sy stem-zlib --with-gnu-as --enable-decimal-float = yes --enable-libgomp --enable-threads - -with-libiconv -prefix = / mingw32 --with-libintl-prefix = / mingw --disable-bootstrap LDFLAGS = -s CFLAGS = -D_USE_32BIT_TIM E_T线程模型:win32 gcc版本4.8.1(GCC)

1 个解决方案

#1


Constraints are are not register names, by specifying the constraint "ebx" you are permitting the compiler to use a signed 32-bit constant , the RBX/EBX/BX/BL register or any SSE register. GCC has chosen to use a constant and will replace any occurrence of %1 with the constant.

约束不是寄存器名称,通过指定约束“ebx”允许编译器使用带符号的32位常量,RBX / EBX / BX / BL寄存器或任何SSE寄存器。 GCC已选择使用常量,并将使用常量替换任何出现的%1。

To use the registers you wish you require the constraints a, b and d.

要使用您希望的寄存器,您需要约束a,b和d。

#1


Constraints are are not register names, by specifying the constraint "ebx" you are permitting the compiler to use a signed 32-bit constant , the RBX/EBX/BX/BL register or any SSE register. GCC has chosen to use a constant and will replace any occurrence of %1 with the constant.

约束不是寄存器名称,通过指定约束“ebx”允许编译器使用带符号的32位常量,RBX / EBX / BX / BL寄存器或任何SSE寄存器。 GCC已选择使用常量,并将使用常量替换任何出现的%1。

To use the registers you wish you require the constraints a, b and d.

要使用您希望的寄存器,您需要约束a,b和d。