这个asm代码有什么意义?

时间:2017-09-21 17:51:34

标签: c++ assembly x86 x86-64 clang++

obj.CurrSize -= size;
0x00000000003ad2d7 <+183>:  mov eax,0x0    
0x00000000003ad2dc <+188>:  test rax,rax
0x00000000003ad2df <+191>:  je 0x3ad2e6 <+198> 
0x00000000003ad2e1 <+193>:  call 0x0
0x00000000003ad2e6 <+198>:  mov rax, 0xffffffffffffff60 
0x00000000003ad2ed <+205>:  sub rbx,r15
0x00000000003ad2f0 <+208>:  add QWORD PTR fs:[rax],rbx`

为什么要测试零,如果为零,则跳过一条指令,否则也会这样做?

1 个答案:

答案 0 :(得分:2)

阅读一个不相关的问题exposes a pattern that looked similar to yours,我想我找到了你的奇怪代码的来源。

很可能这段代码来自与线程相关的C ++ 11功能的扩展,特别是使用__gthread_active_p()检查pthread库是否实际链接的内容。

大多数可能处理libstdc ++中的线程问题的代码(但在没有线程支持的情况下有合理的回退)会被

所困扰

if(__gthread_active_p())

反过来通常归结为检查符号__pthread_key_create是否定义为与NULL不同的内容。这里的技巧是这样的函数声明__attribute__ ((weak)),所以,如果没有提供定义(即如果pthread库没有链接),而不是抱怨,链接器只是将其引用解析为NULL。

因此,您在代码中看到的是编译器留下来执行线程相关内容的检查(比如,获取保护某些共享资源的互斥锁)。预链接代码可能类似于:

    mov eax,__pthread_key_create
    test rax,rax
    jz .skip_mutex_init
    call __pthread_init_some_mutex
.skip_mutex_init:
    mov rax, 0xffffffffffffff60 
    sub rbx,r15
    add QWORD PTR fs:[rax],rbx`

您可以看到解析为__pthread指针的所有NULL符号。当然,生成的代码非常愚蠢 - 编译器无法知道链接器是否将使用-lpthread进行调用,而链接器只执行愚蠢的替换 - 它运行起来太迟了优化器再次启动(除非LTO已启用,但这是一个完全不同的游戏)。

您可以看到类似的模式playing with the compiler explorer:尝试启用/禁用链接完整二进制文件(右侧带有11010标题的按钮),以及在命令行上添加/删除-pthread

现在,我没有设法重现您的结果,但可能来自使用的libstdc++的不同版本,或者代码中使用了不同的线程感知组件(我刚试过使用std::mutexstd::shared_ptr)。