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/C++;:&引用;模块2“;不产生与“相同的说明”;和1“;(gcc-O3)_C_Assembly_Gcc_Compiler Optimization - Fatal编程技术网

C/C++;:&引用;模块2“;不产生与“相同的说明”;和1“;(gcc-O3)

C/C++;:&引用;模块2“;不产生与“相同的说明”;和1“;(gcc-O3),c,assembly,gcc,compiler-optimization,C,Assembly,Gcc,Compiler Optimization,当使用gcc和最大优化(gcc 11.1.0,gcc-std=c11-O3)编译这两个代码段时,我希望得到完全相同的可执行文件,因为%2和&1操作是等价的。但是,在使用objdump进行反汇编之后,这两个对象文件有所不同。输出如下所示 及 int main(int argc,char**argv){ 返回argc&1; } 0000000000001020: 1020:89 fa mov%edi,%edx 1022:c1 ea 1f shr$0x1f,%edx 1025:8d 04 17 le

当使用gcc和最大优化(gcc 11.1.0,
gcc-std=c11-O3
)编译这两个代码段时,我希望得到完全相同的可执行文件,因为
%2
&1
操作是等价的。但是,在使用
objdump
进行反汇编之后,这两个对象文件有所不同。输出如下所示

int main(int argc,char**argv){
返回argc&1;
}
0000000000001020:
1020:89 fa mov%edi,%edx
1022:c1 ea 1f shr$0x1f,%edx
1025:8d 04 17 lea(%rdi,%rdx,1),%eax
1028:83 e0 01和$0x1,%eax
102b:29 d0子%edx,%eax
102d:c3 ret
102e:66 90 xchg%ax,%ax
我理解第一个程序中的指令,但我不太明白第二个程序中某些行的目的

  • shr$0x1f,%edx
    应表示“右移31位
    %edx
  • lea(%rdi,%rdx,1),%eax应表示“保存在
    %eax
    地址
    %rdi+%rdx*1
    处保存的值”

为什么这两个项目不同?为什么编译器没有将
%2
优化为
&1
,这据说更快,使用的指令更少?

val%2
如果
val
为负值,则可能为负值
val&1
将仅具有正值(或零)。因此,这些操作不相同-因此编译代码不同。

您使用了有符号整数,其中
%2
不等同于
&1
,如果将其强制转换为
无符号
,编译器将(可能)生成相同的代码。在锁紧螺栓上是这样。
%2
&1
对于负数不等效
x%2
x&1
不同,因为
x%2
如果x是负数和奇数,则为-1。编译器必须知道
argc
不能是负数。您对
lea
的解释似乎是错误的。它的意思是“加载有效地址”,在
%eax
中加载
%rdi
%rdx
的总和。shr指令的目的是隔离符号位,以便在值为负值时获得不同的行为。好的,没错,我尝试使用
无符号int
,它实际上生成了正确的代码。非常感谢。
0000000000001020 <main>:
    1020:       89 f8                   mov    %edi,%eax
    1022:       83 e0 01                and    $0x1,%eax
    1025:       c3                      ret    
    1026:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1) 
0000000000001020 <main>:
    1020:       89 fa                   mov    %edi,%edx
    1022:       c1 ea 1f                shr    $0x1f,%edx
    1025:       8d 04 17                lea    (%rdi,%rdx,1),%eax
    1028:       83 e0 01                and    $0x1,%eax
    102b:       29 d0                   sub    %edx,%eax
    102d:       c3                      ret    
    102e:       66 90                   xchg   %ax,%ax