Ale*_*dre 33 c c++ intel visual-c++-2012
我今天早上在这里思考,最好的方法是将一些积极转为负面,从消极转为正面,当然,最简单的方法可能是:
int a = 10;
a = a*(-1);
Run Code Online (Sandbox Code Playgroud)
要么
int a = 10;
a = -a;
Run Code Online (Sandbox Code Playgroud)
但是,我想,我接着这样做,使用命令shift和指针......真的可以使用命令移位运算符和内存来改变值的符号吗?
Arm*_*yan 39
使用可读的东西,例如
a *= -1;
Run Code Online (Sandbox Code Playgroud)
要么
a = -a;
Run Code Online (Sandbox Code Playgroud)
将剩下的部分留给优化器.
Ani*_*nge 23
第一个产生:
.file "optimum.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $10, 12(%esp) ;i = 10
negl 12(%esp) ;i = -i
movl $0, %eax
leave
ret
Run Code Online (Sandbox Code Playgroud)
第二个产生:
.file "optimum.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $10, 12(%esp) ;i = 10
negl 12(%esp) ;i = -i
movl $0, %eax
leave
ret
Run Code Online (Sandbox Code Playgroud)
相同的输出!生成的汇编代码没有区别.
--------------------------编辑,OP回答他使用VC++ 2012,INTEL ARCH ----------- --------
编译使用 cl optimum.c /Fa optimum.asm
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01
TITLE C:\Users\Dell\Downloads\TTH\TTH\TTH\optimum.c
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_a$ = -4 ; size = 4
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_main PROC
; File c:\users\dell\downloads\tth\tth\tth\optimum.c
; Line 4
push ebp
mov ebp, esp
push ecx
; Line 5
mov DWORD PTR _a$[ebp], 10 ; 0000000aH
; Line 6
mov eax, DWORD PTR _a$[ebp]
neg eax ;1 machine cycle!
mov DWORD PTR _a$[ebp], eax
; Line 7
xor eax, eax
; Line 8
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
Run Code Online (Sandbox Code Playgroud)
并采用第二种方法(a = a*-1)
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01
TITLE C:\Users\Dell\Downloads\TTH\TTH\TTH\optimum.c
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_a$ = -4 ; size = 4
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_main PROC
; File c:\users\dell\downloads\tth\tth\tth\optimum.c
; Line 4
push ebp
mov ebp, esp
push ecx
; Line 5
mov DWORD PTR _a$[ebp], 10 ; 0000000aH
; Line 6
mov eax, DWORD PTR _a$[ebp]
imul eax, -1 ;1 instruction, 3 machine/cycles :|
mov DWORD PTR _a$[ebp], eax
; Line 7
xor eax, eax
; Line 8
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
Run Code Online (Sandbox Code Playgroud)
其他答案正确表明可读性更重要:
a = -a并a *= -1完全相同,并且无论你如何编写它们,它们都会发出他们认为在目标CPU上最有效的任何asm.(例如,用于x86 gcc/MSVC/clang和ARM gcc的Godbolt编译器资源管理器.)
= -a,3个用于*= -1最近的Intel CPU imul.
然而,这个成语有一个实际的优点*= -1:你只需要写一次左手边,它只被评估一次 - 读者只需要读一次!当LHS长,复杂或昂贵或可能有副作用时,这是相关的:
(valid ? a : b)[prime_after(i++)] *= -1;
*look_up (input) *= -1; // Where look_up may have side-effects
parity[state][(unsigned int)getc(stdin)] *= -1;
variable_with_a_long_explanatory_name *= -1;
Run Code Online (Sandbox Code Playgroud)
一旦采用了成语,人们就会在其他情况下坚持使用.