如果gcc -O3没有“ volatile”,为什么简单的C“ hello world”程序不起作用?

时间:2018-11-29 23:22:59

标签: c gcc optimization inline-assembly

我有以下C程序

int main() {
char string[] = "Hello, world.\r\n";
__asm__ volatile ("syscall;" :: "a" (1), "D" (0), "S" ((unsigned long) string), "d" (sizeof(string) - 1)); }
我想在x86 64位Linux下运行

。我将此系统调用称为“写入”,将0作为fd参数,因为它是stdout。

如果我在带有-O3的gcc下编译,则无法正常工作。看汇编代码

    .file   "test_for_o3.c"
.text
.section    .text.startup,"ax",@progbits
.p2align 4,,15
.globl  main
.type   main, @function
main:
.LFB0:
    .cfi_startproc
    subq    $40, %rsp
    .cfi_def_cfa_offset 48
    xorl    %edi, %edi
    movl    $15, %edx
    movq    %fs:40, %rax
    movq    %rax, 24(%rsp)
    xorl    %eax, %eax
    movq    %rsp, %rsi
    movl    $1, %eax
#APP
# 5 "test_for_o3.c" 1
    syscall;
# 0 "" 2
#NO_APP
    movq    24(%rsp), %rcx
    xorq    %fs:40, %rcx
    jne .L5
    xorl    %eax, %eax
    addq    $40, %rsp
    .cfi_remember_state
    .cfi_def_cfa_offset 8
    ret
.L5:
    .cfi_restore_state
    call    __stack_chk_fail@PLT
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0"
    .section    .note.GNU-stack,"",@progbits

告诉我们gcc根本没有将字符串数据放入汇编代码中。相反,如果我将“ string”声明为“ volatile”,则可以正常工作。

但是,“易失性”的思想只是将其用于可以通过意外事件(从执行函数的角度)改变其值的变量,不是吗? “易失性”会使代码变慢得多,因此,如果可能,应避免使用它。

正如我想的那样,gcc必须假设“ string”的内容一定不能被忽略,因为指针“ string”被用作内联汇编中的输入参数(而gcc不知道内联汇编代码将是什么)这样做)。

如果这是gcc的“允许”行为,那么我在哪里可以阅读有关为-O3编写代码时必须了解的所有形式约束的更多信息?

第二个问题是“ volatile”语句和内联汇编指令的确切作用。我只是习惯用“ volatile”标记所有内联汇编指令,因为在某些情况下它不能正常工作。

0 个答案:

没有答案