I am confused in the following snippet:
movsx ecx, [ebp+var_8] ; signed move
cmp ecx, [ebp+arg_0]
jnb short loc_401027 ; unsigned jump
This seems to conflict. Var_8 appears to be signed on the account of it getting sign-extended. Yet, jnb implies var_8 is not signed on the account it is an unsigned comparsion.
So, is var_8 signed or unsigned? And what about arg_0?
As noted by Jester, unsigned comparison can be used to do range checks for signed numbers. For example, a common C expression that checks whether an index is between 0 and some limit:
Here
idx, after sign-extension, is a signed 32-bit number (int). The idea is, when comparing it withlimitas if it were unsigned, it does both comparisons at once.idxis positive, then "signed" or "unsigned" doesn't matter, so unsigned comparison gives the correct answer.idxis negative, then interpreting it as an unsigned number will yield a very big number (greater than 231-1), so in this case, unsigned comparison also gives the correct answer.So one unsigned comparison does the work of two signed comparisons. This only works when
limitis signed and non-negative. If the compiler can prove it's non-negative, it will generate such optimized code.Another possibility is if the initial C code is buggy and it compares signed with unsigned. A somewhat surprising feature of C is that when a signed variable is compared with unsigned, the effect is unsigned comparison.