Mike L
Mike L

Reputation: 2035

Jump not signed instruction in c

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

Answers (2)

Alexis Wilke
Alexis Wilke

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

merlin2011
merlin2011

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

Related Questions