1.14. CONDITIONAL JUMPS
$LN3@f_signed:
mov ecx, DWORD PTR _a$[ebp]
cmp ecx, DWORD PTR _b$[ebp]
jne SHORT $LN2@f_signed
push OFFSET $SG739 ; 'a==b'
call _printf
add esp, 4
$LN2@f_signed:
mov edx, DWORD PTR _a$[ebp]
cmp edx, DWORD PTR _b$[ebp]
jge SHORT $LN4@f_signed
push OFFSET $SG741 ; 'a<b'
call _printf
add esp, 4
$LN4@f_signed:
pop ebp
ret 0
_f_signed ENDP
The first instruction,JLE, stands forJump if Less or Equal. In other words, if the second operand is larger
or equal to the first one, the control flow will be passed to the address or label specified in the instruction.
If this condition does not trigger because the second operand is smaller than the first one, the control
flow would not be altered and the firstprintf()would be executed. The second check isJNE:Jump if Not
Equal. The control flow will not change if the operands are equal.
ThethirdcheckisJGE:JumpifGreaterorEqual—jumpifthefirstoperandislargerthanthesecondorifthey
are equal. So, if all three conditional jumps are triggered, none of theprintf()calls would be executed
whatsoever. This is impossible without special intervention. Now let’s take a look at thef_unsigned()
function. Thef_unsigned()function is the same asf_signed(), with the exception that theJBEandJAE
instructions are used instead ofJLEandJGE, as follows:
Listing 1.107: GCC
_a$ = 8 ; size = 4
_b$ = 12 ; size = 4
_f_unsigned PROC
push ebp
mov ebp, esp
mov eax, DWORD PTR _a$[ebp]
cmp eax, DWORD PTR _b$[ebp]
jbe SHORT $LN3@f_unsigned
push OFFSET $SG2761 ; 'a>b'
call _printf
add esp, 4
$LN3@f_unsigned:
mov ecx, DWORD PTR _a$[ebp]
cmp ecx, DWORD PTR _b$[ebp]
jne SHORT $LN2@f_unsigned
push OFFSET $SG2763 ; 'a==b'
call _printf
add esp, 4
$LN2@f_unsigned:
mov edx, DWORD PTR _a$[ebp]
cmp edx, DWORD PTR _b$[ebp]
jae SHORT $LN4@f_unsigned
push OFFSET $SG2765 ; 'a<b'
call _printf
add esp, 4
$LN4@f_unsigned:
pop ebp
ret 0
_f_unsigned ENDP
As already mentioned, the branch instructions are different:JBE—Jump if Below or EqualandJAE—Jump
if Above or Equal. These instructions (JA/JAE/JB/JBE) differ fromJG/JGE/JL/JLEin the fact that they work
with unsigned numbers.
See also the section about signed number representations (2.2 on page 452). That is why if we seeJG/JL
in use instead ofJA/JBor vice-versa, we can be almost sure that the variables are signed or unsigned,
respectively. Here is also themain()function, where there is nothing much new to us: