小编J.S*_*ith的帖子

条件分支的落后方更有效吗?把它作为错误处理方面是一个好主意吗?

考虑一个调用另一个函数并检查错误的函数.假设函数CheckError()在失败时返回0,其他数字表示成功.

第一个版本:取得成功分支或落入错误处理代码(位于函数中间).

    CALL   CheckError
    TEST   EAX,EAX    ;check if return value is 0
    JNZ    Normal
ErrorProcessing:
    ...    ;some error processing code here
Normal:
    ...    ;some usual code here
Run Code Online (Sandbox Code Playgroud)

第二个版本在错误时采取分支,或者通过正常路径.错误处理代码位于函数的末尾.

    CALL   CheckError
    TEST   EAX,EAX
    JZ     ErrorProcessing
Normal:
    ...    ;some usual code here
ErrorProcessing:
    ...    ;some error processing code here
Run Code Online (Sandbox Code Playgroud)

这两种方法中哪一个更好?为什么?

就个人而言,我认为第一个代码具有更好的代码结构(更易读和可编程),因为代码是紧凑的.但是,我也认为第二个代码通常具有更好的速度(在无错误的情况下),因为一个未采用的条件跳转需要2-3个时钟周期(可能我在这里太挑剔)少于一个.

无论如何,我发现我测试的所有编译器在编译if语句时都使用第一个模型.例如:

if (GetActiveWindow() == NULL)
{
    printf("Error: can't get window's handle.\n");
    return -1;
}
printf("Succeed.\n");
return 0;
Run Code Online (Sandbox Code Playgroud)

这应编译为(没有任何exe入口例程):

    CALL [GetActiveWindow]    ;if (GetActiveWindow() == NULL)
    TEST …
Run Code Online (Sandbox Code Playgroud)

optimization x86 assembly micro-optimization

3
推荐指数
1
解决办法
425
查看次数

按照每个通用寄存器的用途编写x86汇编是否必要或更容易

一般来说,按照每个寄存器的用途编码x86汇编是否必要或更容易?

x86架构中的寄存器每个都是首先设计用于特殊目的,但现代编译器似乎并不关心它们的使用(除非在某些特殊条件下,例如REP MOV或MUL).

那么,取决于每个寄存器的用途,代码是更容易还是更优化?(不管与某些寄存器相同的特殊指令(或编码))

例如(我可以改用REP MOVSB或LODSB STOSB,但只是为了演示):

第一个代码:

LEA ESI,[AddressOfSomething]
LEA EDI,[AddressOfSomethingElse]
MOV ECX,NUMBER_OF_LOOP
LoopHere:
MOV AL,[ESI]
ADD AL,8
MOV [EDI],AL
ADD ESI,1
ADD EDI,1
CMP AL,0
JNZ LoopHere
TheEnd:
;...
Run Code Online (Sandbox Code Playgroud)

第二代码:

LEA ECX,[AddressOfSomething]
LEA EDX,[AddressOfSomethingElse]
MOV EBX,NUMBER_OF_LOOP
LoopHere:
MOV AL,[ECX]
ADD AL,8
MOV [EDX],AL
ADD ECX,1
ADD EDX,1
CMP AL,0
JNZ LoopHere
TheEnd:
;...
Run Code Online (Sandbox Code Playgroud)

我使用的编译器 - Visual Studio 2015在执行这样的任务时通常使用第二种方法,它不使用寄存器取决于它的用途,相反,编译器只根据其"volatile"选择使用哪个寄存器或"非易失性"特征(在调用函数后).因此,所有高级编程语言编程软件反汇编都使用第二种方法.

另一个有趣的事实是,在ARM语言中,GPR都具有相同的用途,并且被命名为R0-R7,这意味着当代码使用它时,代码将更类似于第二代码.

总而言之,我的观点是这两个代码使用相同的指令,因此无论我使用哪个寄存器,它都应该具有相同的速度.但我是对的吗?哪个代码更容易编码?

c++ optimization x86 assembly cpu-registers

3
推荐指数
1
解决办法
121
查看次数