Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这个asm代码的意义是什么? obj.CurrSize-=大小; 0x00000000003ad2d7:mov eax,0x0 0x00000000003ad2dc:测试rax,rax 0x00000000003ad2df:je 0x3ad2e6 0x00000000003ad2e1:调用0x0 0x00000000003ad2e6:mov rax,0xFFFFFFFFFF60 0x00000000003ad2ed:子rbx,r15 0x00000000003ad2f0:添加QWORD PTR fs:[rax],rbx`_C++_Assembly_X86_X86 64_Clang++ - Fatal编程技术网

C++ 这个asm代码的意义是什么? obj.CurrSize-=大小; 0x00000000003ad2d7:mov eax,0x0 0x00000000003ad2dc:测试rax,rax 0x00000000003ad2df:je 0x3ad2e6 0x00000000003ad2e1:调用0x0 0x00000000003ad2e6:mov rax,0xFFFFFFFFFF60 0x00000000003ad2ed:子rbx,r15 0x00000000003ad2f0:添加QWORD PTR fs:[rax],rbx`

C++ 这个asm代码的意义是什么? obj.CurrSize-=大小; 0x00000000003ad2d7:mov eax,0x0 0x00000000003ad2dc:测试rax,rax 0x00000000003ad2df:je 0x3ad2e6 0x00000000003ad2e1:调用0x0 0x00000000003ad2e6:mov rax,0xFFFFFFFFFF60 0x00000000003ad2ed:子rbx,r15 0x00000000003ad2f0:添加QWORD PTR fs:[rax],rbx`,c++,assembly,x86,x86-64,clang++,C++,Assembly,X86,X86 64,Clang++,为什么要测试零,如果是零,跳过一条指令,否则也要这样做?阅读一个无关的问题,我想我找到了你奇怪代码的来源 这段代码很可能来自与线程相关的C++11功能的扩展,特别是使用\uugthread\u active\u p()检查pthread库是否实际链接到了 在libstdc++中,大多数可能需要处理线程问题的代码(但在不需要线程支持的情况下有合理的回退)都是杂乱无章的 obj.CurrSize -= size; 0x00000000003ad2d7 <+183>: mov eax,0

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

阅读一个无关的问题,我想我找到了你奇怪代码的来源

这段代码很可能来自与线程相关的C++11功能的扩展,特别是使用
\uugthread\u active\u p()
检查
pthread
库是否实际链接到了

在libstdc++中,大多数可能需要处理线程问题的代码(但在不需要线程支持的情况下有合理的回退)都是杂乱无章的

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`
这通常归结为检查符号
\uu pthread\u key\u create
是否定义为与
NULL
不同的内容。这里的技巧是,这样一个函数是用
\uuuu属性
声明的,因此,如果没有提供定义(即,如果
pthread
库没有链接),链接器只会将其引用解析为NULL,而不是抱怨

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

if(__gthread_active_p())
在这里,您可以看到所有解析为
NULL
指针的
\pthread
符号。当然,生成的代码非常愚蠢-编译器不知道链接器是否将使用
-lpthread
调用,链接器只是执行愚蠢的替换-再次运行优化器为时已晚(除非启用LTO,但这是一个完全不同的游戏)

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


现在,我没有完全复制您的结果,但可能是因为使用了不同版本的
libstdc++
,或者代码中使用了不同的线程感知组件(我刚刚尝试了
std::mutex
std::shared_ptr
)。

不,
call 0x0
只是调用下一条指令,不是空指针。这是一个已经静态链接的程序的disasm(gdb disasm的输出)。我不确定,IIRC通常gdb转储as
调用0x3ad2e6
,类似于上面的相对跳转。尽管如此,如果它像你说的那样,看起来像是手写代码来停止反编译程序之类的-在函数本身中插入一个伪调用会对重建函数入口点/块的启发式造成严重破坏。哦,糟糕,是的,那是一个空指针加载,而不是
mov-eax,imm32
。我只是不习惯GDB版本的英特尔语法
objdump
将打印
DWORD PTR:0
。(@vladon)我用gdb测试过。绝对0的负载为
mov eax,DWORD PTR ds:0x0
,但
mov eax,imm32
mov eax,0x0
。也许最初的代码是
moveax,OFFSET\u pthread\u key\u create
?是的,我的意思是立即加载。我真的不知道
OFFSET
语法,通常在
nasm
a
mov-reg,label
是指立即加载label的地址,间接加载是
mov-reg,[label]
DWORD-PTR
通常被省略,如果可以通过目标寄存器的大小推断出来的话)。抱歉造成混淆。如果
rax
的上半部分中有任何非零位,将执行
调用0x0
。那么接下来是什么呢?没有堆栈清理的
ret
?然后以递归的形式再次执行这些代码,我不知道。什么C++语句/汇编指令遵循你所张贴的?@彼得科德斯谢谢。这是我们的内部代码。它真的是叮当作响3.9.1与-O2。但如果是,则永远不会执行调用0x0。为什么会有测试和je过度指导?嗯…这是从链接二进制文件中进行的GDB反汇编吗?您是否可以发布
objdump
输出,这样我们就可以查看机器代码字节,以确保这是跳转到地址零,还是跳转到下一条指令。(请再次确认它是链接的二进制文件,而不是带有占位符的对象文件)。(或者只处理那个测试用例,因为这样会更有用。)@PeterCordes调用0x0的机器代码这里是
e8 1a 2d c5 ff
    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`