CHAPTER 12. CONDITIONAL JUMPS CHAPTER 12. CONDITIONAL JUMPS
12.3.1 x86
Old and non-optimizing compilers generate assembly code just as if anif/elsestatement was used:
Listing 12.18: Non-optimizing MSVC 2008
$SG746 DB 'it is ten', 00H
$SG747 DB 'it is not ten', 00H
tv65 = -4 ; this will be used as a temporary variable
_a$ = 8
_f PROC
push ebp
mov ebp, esp
push ecx
; compare input value with 10
cmp DWORD PTR _a$[ebp], 10
; jump to $LN3@f if not equal
jne SHORT $LN3@f
; store pointer to the string into temporary variable:
mov DWORD PTR tv65[ebp], OFFSET $SG746 ; 'it is ten'
; jump to exit
jmp SHORT $LN4@f
$LN3@f:
; store pointer to the string into temporary variable:
mov DWORD PTR tv65[ebp], OFFSET $SG747 ; 'it is not ten'
$LN4@f:
; this is exit. copy pointer to the string from temporary variable to EAX.
mov eax, DWORD PTR tv65[ebp]
mov esp, ebp
pop ebp
ret 0
_f ENDP
Listing 12.19: Optimizing MSVC 2008
$SG792 DB 'it is ten', 00H
$SG793 DB 'it is not ten', 00H
_a$ = 8 ; size = 4
_f PROC
; compare input value with 10
cmp DWORD PTR _a$[esp-4], 10
mov eax, OFFSET $SG792 ; 'it is ten'
; jump to $LN4@f if equal
je SHORT $LN4@f
mov eax, OFFSET $SG793 ; 'it is not ten'
$LN4@f:
ret 0
_f ENDP
Newer compilers are more concise:
Listing 12.20: Optimizing MSVC 2012 x64
$SG1355 DB 'it is ten', 00H
$SG1356 DB 'it is not ten', 00H
a$ = 8
f PROC
; load pointers to the both strings
lea rdx, OFFSET FLAT:$SG1355 ; 'it is ten'
lea rax, OFFSET FLAT:$SG1356 ; 'it is not ten'
; compare input value with 10
cmp ecx, 10
; if equal, copy value from RDX ("it is ten")
; if not, do nothing. pointer to the string "it is not ten" is still in RAX as for now.
cmove rax, rdx
ret 0
f ENDP
Optimizing GCC 4.8 for x86 also uses theCMOVccinstruction, while the non-optimizing GCC 4.8 uses conditional jumps.