这个 asm 代码的意义是什么?
What is the sense of this asm code?
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::mutex
和std::shared_ptr
)。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 这个 asm 代码的意义是什么?
- C++:如果 0 和 asm 在这些代码行中是什么意思
- asm.js规范中提到的c/c++虚拟机是什么