相关疑难解决方法(0)

为什么GCC在实现整数除法时使用乘以奇数的乘法?

我一直在阅读divmul组装操作,我决定通过在C中编写一个简单的程序来实现它们:

文件分割

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后生成汇编语言代码:

gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)

但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:

mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 integer-division

206
推荐指数
4
解决办法
1万
查看次数

如何从GCC /铿锵声组件输出中消除"噪音"?

我想检查boost::variant在我的代码中应用的程序集输出,以便查看哪些中间调用被优化掉了.

当我编译以下示例(使用GCC 5.3 g++ -O3 -std=c++14 -S)时,似乎编译器优化了所有内容并直接返回100:

(...)
main:
.LFB9320:
    .cfi_startproc
    movl    $100, %eax
    ret
    .cfi_endproc
(...)
Run Code Online (Sandbox Code Playgroud)
#include <boost/variant.hpp>

struct Foo
{
    int get() { return 100; }
};

struct Bar
{
    int get() { return 999; }
};

using Variant = boost::variant<Foo, Bar>;


int run(Variant v)
{
    return boost::apply_visitor([](auto& x){return x.get();}, v);
}
int main()
{
    Foo f;
    return run(f);
}
Run Code Online (Sandbox Code Playgroud)

但是,完整的程序集输出包含的内容远远超过上面的摘录,对我而言,它看起来永远不会被调用.有没有办法告诉GCC/clang删除所有"噪音"并输出程序运行时实际调用的内容?


完整装配输出:

    .file   "main1.cpp"
    .section    .rodata.str1.8,"aMS",@progbits,1
    .align 8
.LC0:
    .string "/opt/boost/include/boost/variant/detail/forced_return.hpp"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC1: …
Run Code Online (Sandbox Code Playgroud)

c++ assembly gcc clang

56
推荐指数
3
解决办法
1万
查看次数

gcc究竟如何做优化?

为了知道gcc究竟如何进行优化,我编写了两个用-O2编译的程序,但是汇编代码有一些区别.在我的程序中,我想在循环中输出"hello",并在每个输出之间添加一些延迟.这两个程序仅用于说明我的问题,我知道我可以在程序1中使用volatile或asm来实现我的目的.

计划1

#include <stdio.h>

int main(int argc, char **argv)
{
    unsigned long i = 0;
    while (1) {
        if (++i > 0x1fffffffUL) {
            printf("hello\n");
            i = 0;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用-O2编译,汇编代码是:

Disassembly of section .text.startup:

00000000 <_main>:
#include <stdio.h>

int main(int argc, char **argv)
{
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 10                sub    $0x10,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   66 90                   xchg   %ax,%ax …
Run Code Online (Sandbox Code Playgroud)

c optimization gcc compiler-optimization

5
推荐指数
1
解决办法
259
查看次数

GCC 优化器从 5.1 开始就被破坏了吗?

我正在观看一个旧视频Jason Turner:实用表演实践

一开始就有一个 GCC 5.1 中优化代码的示例:

#include <string>

int main() {
    return std::string("a").size();
}
Run Code Online (Sandbox Code Playgroud)

编译为“无”:

main:
        mov     eax, 1
        ret
Run Code Online (Sandbox Code Playgroud)

然而,我很惊讶地看到 GCC 13.2 的另一个输出:

main:
        sub     rsp, 40
        lea     rax, [rsp+16]
        mov     rdi, rsp
        mov     QWORD PTR [rsp+8], 1
        mov     QWORD PTR [rsp], rax
        mov     eax, 97
        mov     WORD PTR [rsp+16], ax
        call    std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()
        mov     eax, 1
        add     rsp, 40
        ret
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/45PWox4Gb

std::string.size()这是 GCC自 5.1(根据评论是 12.3)以来一直无法持续传播的错误吗?-std=它过去常常在没有参数的情况下做到这一点-O3。新版本需要-std=c++20提供相同的输出。

c++ gcc compiler-optimization

5
推荐指数
0
解决办法
103
查看次数

X86 汇编:.text.startup 部分和 .text 部分有什么区别

    .file   "test-instr.c"
    .text
.Ltext0:
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "Hum?"
.LC1:
    .string "Looks like a zero to me!"
.LC2:
    .string "A non-zero value? How quaint!"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
/* --- trampoline malloc shm space begin --- */ 

.align 4 

.section .data 
shmSize: .quad 8 * 4 * 0x10000 
.global shmptr
shmptr: .quad 0
.section .text
.extern malloc 
movq (shmSize), %rdi 
call malloc 
movq %rax, (shmptr) 
/* --- trampoline malloc shm spacd end --- */ …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc gnu-assembler sections

3
推荐指数
1
解决办法
1845
查看次数