为什么VS imul rax,rax,0而不是简单的举动?

马克西·科兹克(Maciej Kozik)

我正在查看为这个简单的x64程序生成的程序集Visual Studio:

struct Point {
    int a, b;

    Point() {
        a = 0; b = 1;
    }
};

int main(int argc, char* argv[])
{
    Point arr[3];
    arr[0].b = 2;
    return 0;
}

并且当它遇到arr [0] .b = 2时,它将生成以下代码:

mov eax, 8
imul rax, rax, 0
mov dword ptr [rbp+rax+4],2

为什么要执行imul rax,rax,0而不是简单的mov rax,0甚至是xor rax,rax如果有的话,imul如何更有效?

弗兰克·C。

卡马奇

原因是因为程序集正在计算Point数组中对象(恰好在堆栈上)的偏移量以及变量的偏移量b

imul具有三(3)个操作数的英特尔文档状态:

三操作数形式—此形式需要一个目标操作数(第一个操作数)和两个源操作数(第二个和第三个操作数)。在此,将第一源操作数(可以是通用寄存器或存储位置)乘以第二源操作数(立即数)。中间乘积(第一个源操作数的大小的两倍)被截断并存储在目标操作数(通用寄存器)中。

在您的情况下,它正在计算对象在数组中的偏移量,从而导致寻址Point堆栈中的第一个(第零个)位置。有了这样的决心则是增加的偏移量.b这是+4如此细分:

mov  eax,8                   ; prepare to offset into the Point array
imul rax, rax, 0             ; Calculate which Point object is being referred to
mov  dword ptr [rbp+rax+4],2 ; Add the offset to b and move value 2 in

操作说明。所有这些都解决了arr[0].b = 2

我认为您没有使用积极的优化进行编译。在进行直接编译(不进行优化,调试等)时,编译器不会对寻址进行任何假设。

与c比较

clang 3.9.0没有优化标志且没有优化标志的OS X(El Capitan)上,一旦Point在数组中实例化对象,就.b = 2可以简单地分配

mov dword ptr [rbp - 44], 2

在这种情况下,clang对偏移量非常了解,并且可以在默认优化过程中解决寻址问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么要使用Math.imul()?

来自分类Dev

为什么要使用Math.imul()?

来自分类Dev

imul指令的ZF行为是什么?

来自分类Dev

为什么mov rax,cr0会导致nasm 64位中的分段错误

来自分类Dev

执行“movq %rax, (%rdi)”后 %rax 会发生什么?

来自分类Dev

gcc内联asm中的data32 data32 nopw%cs:0x0(%rax,%rax,1)指令是什么意思?

来自分类Dev

为什么我要添加 rax 和 rdx?

来自分类Dev

为什么#if 0 vs #if(1> 1)?

来自分类Dev

为什么#if 0 vs #if(1> 1)?

来自分类Dev

使用较小的寄存器有什么好处,例如al vs eax / rax

来自分类Dev

使用较小的寄存器有什么好处,例如al vs eax / rax

来自分类Dev

为什么此功能将RAX作为第一个操作推入堆栈?

来自分类Dev

为什么libc nanosleep中的寄存器rax上存在紧密的轮询循环?

来自分类Dev

为什么在TRACE_IRQS_OFF之前将rax设置为-ENOSYS

来自分类Dev

为什么要将相同的值复制到他已经拥有的 rax 中?

来自分类Dev

为什么 rax 和 rdi 在这种情况下工作相同?

来自分类Dev

敌人的举动为什么错了?

来自分类Dev

为什么不是“ 0” ==“ 0”?

来自分类Dev

RAX寄存器的名称是什么?

来自分类Dev

imul指令的第三个操作数是一个内存地址,它的原始值是什么?

来自分类Dev

TOP(1)vs MIN问题-为什么SQL Server为什么使用群集扫描而不是查找覆盖索引?

来自分类Dev

imul指令如何计算符号标志?

来自分类Dev

常数相乘-imul或shl-add-combination

来自分类Dev

为什么对memset使用'\ 0'而不是0?

来自分类Dev

为什么对memset使用'\ 0'而不是0?

来自分类Dev

为什么VS和Windbg即使在调试版本中也将“ this”指针打印为“ 0xcccccccc”?

来自分类Dev

为什么VS和Windbg即使在调试版本中也将“ this”指针打印为“ 0xcccccccc”?

来自分类Dev

为什么输出显示0而不是0.0?

来自分类Dev

为什么!0等于1而不是-1?

Related 相关文章

  1. 1

    为什么要使用Math.imul()?

  2. 2

    为什么要使用Math.imul()?

  3. 3

    imul指令的ZF行为是什么?

  4. 4

    为什么mov rax,cr0会导致nasm 64位中的分段错误

  5. 5

    执行“movq %rax, (%rdi)”后 %rax 会发生什么?

  6. 6

    gcc内联asm中的data32 data32 nopw%cs:0x0(%rax,%rax,1)指令是什么意思?

  7. 7

    为什么我要添加 rax 和 rdx?

  8. 8

    为什么#if 0 vs #if(1> 1)?

  9. 9

    为什么#if 0 vs #if(1> 1)?

  10. 10

    使用较小的寄存器有什么好处,例如al vs eax / rax

  11. 11

    使用较小的寄存器有什么好处,例如al vs eax / rax

  12. 12

    为什么此功能将RAX作为第一个操作推入堆栈?

  13. 13

    为什么libc nanosleep中的寄存器rax上存在紧密的轮询循环?

  14. 14

    为什么在TRACE_IRQS_OFF之前将rax设置为-ENOSYS

  15. 15

    为什么要将相同的值复制到他已经拥有的 rax 中?

  16. 16

    为什么 rax 和 rdi 在这种情况下工作相同?

  17. 17

    敌人的举动为什么错了?

  18. 18

    为什么不是“ 0” ==“ 0”?

  19. 19

    RAX寄存器的名称是什么?

  20. 20

    imul指令的第三个操作数是一个内存地址,它的原始值是什么?

  21. 21

    TOP(1)vs MIN问题-为什么SQL Server为什么使用群集扫描而不是查找覆盖索引?

  22. 22

    imul指令如何计算符号标志?

  23. 23

    常数相乘-imul或shl-add-combination

  24. 24

    为什么对memset使用'\ 0'而不是0?

  25. 25

    为什么对memset使用'\ 0'而不是0?

  26. 26

    为什么VS和Windbg即使在调试版本中也将“ this”指针打印为“ 0xcccccccc”?

  27. 27

    为什么VS和Windbg即使在调试版本中也将“ this”指针打印为“ 0xcccccccc”?

  28. 28

    为什么输出显示0而不是0.0?

  29. 29

    为什么!0等于1而不是-1?

热门标签

归档