flat assembler
Message board for the users of flat assembler.
Index
> Windows > Eliminating branches |
Author |
|
cod3b453 15 Sep 2012, 07:36
The simplest way is to "inline" sections of code; this may mean having local copies of code duplicated in a section to prevent branching/calling or loop unrolling so that more iterations are executed between loop branches.
As you've hinted, the carry flag (CF) can be used; usually this works well for cases where a statement such as: Code: A_ENABLE = 0x20 ; Must be single bit in this example B_ENABLE = 0x01 ; Must be 1 for this example to match CF B_COMMON = 0x10 if a and A_ENABLE then b := B_COMMON else b := B_COMMON or B_ENABLE end Code: CF := (a and A_ENABLE) ? 1 : 0 b := B_COMMON or (not CF) Code: sar eax,6 ; A_ENABLE shr 6 = 0.1 (CF=1) cmc ; CF := not CF adc ebx,B_COMMON ; b := b + B_COMMON + not CF Another trick is lookup tables (LUT), where an if or select statement on a value that is small (eg. 0,1,...,n-1) can be reduced to a LUT of size n and simply looking up the values has the same result as multiple branches to the right condition. I'm sure there as more but those are all I can remember right now |
|||
15 Sep 2012, 07:36 |
|
JohnFound 15 Sep 2012, 07:41
The most common way is to use CMOV instruction.
There are some other tricks, but they are solutions to a particular problems. For example function ABS: Code: mov edx, eax sar edx, 31 xor eax, edx sub eax, edx Min: Code: sub ebx,eax sbb ecx,ecx and ecx,ebx add eax,ecx Max: Code: sub ebx,eax sbb ecx,ecx not ecx and ecx,ebx add eax,ecx Note however, that such tricks will make your code less readable, so such an optimizations should be kept for the later state of development, when the program works and bugs are cleared more or less. |
|||
15 Sep 2012, 07:41 |
|
AsmGuru62 15 Sep 2012, 12:14
Also there are setCC instructions.
Here is a couple of examples. 1. During parsing of an integer value, which can be negative. Code: ; ; ESI = text with an integer value ; can be "7357632" (no negative sign) ; can be "-73282" (negative sign present) ; xor ecx, ecx cmp byte [esi], '-' sete cl add esi, ecx ; ; ESI ^^^ will move forward 1 byte if negative sign present ; 2. Or to set up one of two cursors: Code: CursorsHV DD 0,0 ... ; ; Load both cursors (somewhere at startup) ; mov ebx, [hInstance] mov edi, CursorsHV invoke LoadCursor, ebx, IDR_CURSOR_HORZ stosd invoke LoadCursor, ebx, IDR_CURSOR_VERT stosd ... ; ; Set up one of two cursors, depending on some flag ; xor ecx, ecx cmp [IsVerticalResize], 1 sete cl invoke SetCursor, [CursorsHV + ecx*4] |
|||
15 Sep 2012, 12:14 |
|
LocoDelAssembly 15 Sep 2012, 14:27
Code: sar eax,6 ; A_ENABLE shr 6 = 0.1 (CF=1) cmc ; CF := not CF adc ebx,B_COMMON ; b := b + B_COMMON + not CF Code: sar eax,6 ; A_ENABLE shr 6 = 0.1 (CF=1) sbb ebx,-B_COMMON - 1 ; b := b + B_COMMON + not CF |
|||
15 Sep 2012, 14:27 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.