这个 asm 代码的意义是什么?

What is the sense of this asm code?

本文关键字:是什么 asm 代码 这个      更新时间:2023-10-16
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`

为什么要测试零,如果为零,则跳过一条指令,否则做同样的事情?

阅读一个不相关的问题,暴露了一个看起来与你相似的模式,我想我找到了你奇怪代码的起源。

这段代码很可能来自与线程相关的 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`

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

您可以看到自己使用编译器资源管理器的类似模式:尝试启用/禁用链接完整二进制文件(右侧带有 11010 标题的按钮),并在命令行上添加/删除-pthread

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