Reputation: 2035
test ecx,ecx
jns 00400000
is this assembly code equivalent to this c code?
int ECX;
if((ECX>>31)==1){..}
if not how can I make it equivalent?
Thanks for your help.
Upvotes: 2
Views: 10597
Reputation: 20818
The test reg,reg
instruction sets flags and that is equivalent to doing a compare in C. So as Jester mentioned reg < 0
means, is the sign bit set.
However, in C you have to be careful about the variable type you are dealing with. In your case, you'd want to use a type such as int32_t
. That way you make sure that you are testing a 32 bit integer. The same code on a 64 bit platform may transform your int
in 64 bits and the sign would be a little further up.
Using a shift in C when you just to a test in assembly is really not equivalent. Actually, if you really wanted to use a shift, you should use an unsigned integer:
if((uint32_t)reg >> 31) { ... }
But really, that's not sensible and much harder to read than the simple:
if(reg < 0) { ... }
Not only that, it will be slower (2 instructions instead of 1, although the compiler may figure out that test reg,reg + jns
would be enough, but you shouldn't count on it.)
Upvotes: 0
Reputation: 75639
Based the Wikipedia entry for the test instruction, the test will set the sign flag of the flags register based on the most significant bit of the register ecx
.
Therefore, the jump is taken iff the MSB
is not set as you have seen. Your complement C
code is almost equivalent, but depending on whether >>
does a logical or arithmetic shift, you should mask it to be safe.
if(((ECX>>31) & 1)==1){..}
Of course, as Jester mentioned, if the signed bit is set, then it is also true that ECX < 0
, so that is a simpler test in this case.
Upvotes: 1