相关疑难解决方法(0)

nop操作码的目的是什么?

我正在通过MSIL并注意到有很多nop指令.MSDN文章称,如果操作码被修补,它们不采取任何操作并用于填充空间.它们在调试版本中比在发布版本中使用得更多.我知道这些语句用于汇编语言,以确保操作码适合字边界,但为什么MSIL需要它?

assembly cil

79
推荐指数
6
解决办法
5万
查看次数

为什么编译器会复制一些指令?

有时编译器生成具有奇怪的指令重复的代码,可以安全地删除.考虑以下代码:

int gcd(unsigned x, unsigned y) {
  return x == 0 ? y : gcd(y % x, x);
}
Run Code Online (Sandbox Code Playgroud)

这是汇编代码(由clang 5.0生成并启用了优化):

gcd(unsigned int, unsigned int): # @gcd(unsigned int, unsigned int)
  mov eax, esi
  mov edx, edi
  test edx, edx
  je .LBB0_1
.LBB0_2: # =>This Inner Loop Header: Depth=1
  mov ecx, edx
  xor edx, edx
  div ecx
  test edx, edx
  mov eax, ecx
  jne .LBB0_2
  mov eax, ecx
  ret
.LBB0_1:
  ret
Run Code Online (Sandbox Code Playgroud)

在以下代码段中:

  mov eax, ecx
  jne .LBB0_2
  mov eax, …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-construction clang

58
推荐指数
2
解决办法
1576
查看次数

为什么 MSVC 为 x64 上的原子加载生成 nop 指令?

如果您编译如下代码

#include <atomic>

int load(std::atomic<int> *p) {
    return p->load(std::memory_order_acquire) + p->load(std::memory_order_acquire);
}
Run Code Online (Sandbox Code Playgroud)

您会看到MSVC在每次内存加载后都会生成 NOP 填充

int load(std::atomic<int> *) PROC
        mov     edx, DWORD PTR [rcx]
        npad    1
        mov     eax, DWORD PTR [rcx]
        npad    1
        add     eax, edx
        ret     0
Run Code Online (Sandbox Code Playgroud)

为什么是这样?有什么办法可以避免它而不放松内存顺序(这会影响代码的正确性)?

c++ x86-64 atomic visual-c++ no-op

8
推荐指数
1
解决办法
366
查看次数

标签 统计

c++ ×2

assembly ×1

atomic ×1

cil ×1

clang ×1

compiler-construction ×1

no-op ×1

visual-c++ ×1

x86-64 ×1