Jump to content
  • Advertisement
Sign in to follow this  
BloodOrange1981

x86 / x64 and the crazy conditional moves based on flags

This topic is 1318 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Evening! 

 

I've been brushing up on some x64 for SIMD and SSE at the assembly level and I was wondering about conditional statements that execute on the carry flag, the parity flag etc

 

I understand that a conditional move based on equality "maps" to c or c++ code like

 

if(x != y){              cmp      x,y

  a = 24               movne   a, 24

}

 

but what about operations based on register flags like the carry flag? I understand the use of the zero flag for loops etc but instructions like cmovc and cmovp have me puzzled how they can be used practically

 

Share this post


Link to post
Share on other sites
Advertisement

I'm not sure if x86/64 CPUs actually use them this way, but if I remember correctly, some old microcontroller architectures I once coded on used the carry flag for > and < comparisons of unsigned integers. They subtracted one value from the other, and depending on which one was larger it would result in the carry flag being set or not, thereby giving you the result of the comparison. So you could do something like

sub A,B
jc label1   //jc = jump if carry is set
jmp label2

label1:
//B was greater than A!

label2:
//A was greater than or equal to B!

Could very well still be this way on modern architectures.

Edited by agleed

Share this post


Link to post
Share on other sites

The ones you mentioned date back to the early 1990s


Make that early 1980s.
My C64's 6510 (6502 variant) had them. At least the carry flag but not sure about parity.

Share this post


Link to post
Share on other sites
if(x != y){ cmp x,y
a = 24 movne a, 24
}

 

Are you sure you were reading about x86/x64? Because MOVNE is an ARM instruction...

Edited by tonemgub

Share this post


Link to post
Share on other sites

if(x != y){ cmp x,y
a = 24 movne a, 24
}

 
Are you sure you were reading about x86/x64? Because MOVNE is an ARM instruction...


Well, x86's is (F)CMOVNE|Z, but we all still knew what he meant... Edited by Nypyren

Share this post


Link to post
Share on other sites


I understand that a conditional move based on equality "maps" to c or c++ code like

,,,

but what about operations based on register flags like the carry flag? I understand the use of the zero flag for loops etc but instructions like cmovc and cmovp have me puzzled how they can be used practically

 

You try to reason about assembler at the wrong abstraction level; machine instructions have a direct and simple correspondence with high level variables, arithmetic, loops etc. only in easy cases, and optimizations (like using conditional move instructions rather than jumps and plain moves) tend to depart from the easy cases.

Share this post


Link to post
Share on other sites

There are also some assembly instructions which are redundant and only exist to make intentions behind handwritten assembly code a little more clear.

For example, jc translates to the same machine code as jb and jnae, but one tells the reader you test the flag while the others tell about testing the comparison of two numbers.

Share this post


Link to post
Share on other sites

Evening! 

 

I've been brushing up on some x64 for SIMD and SSE at the assembly level and I was wondering about conditional statements that execute on the carry flag, the parity flag etc

 

I understand that a conditional move based on equality "maps" to c or c++ code like

 

if(x != y){              cmp      x,y

  a = 24               movne   a, 24

}

 

but what about operations based on register flags like the carry flag? I understand the use of the zero flag for loops etc but instructions like cmovc and cmovp have me puzzled how they can be used practically

 

 

To figure this out, you should consider what kinds of operations affect those other flags, what those flags mean, and what language constructs they map to.

 

For example, how does that MOVNE know whether or not to move? It checks the zero flag - CMP works by subtracting one operand form the other, setting CPU flags based on the result, and then discarding the result.  So if x equals y, then y-x equals 0 and the CMP sets the Zero flag, but if x and y are not equal, then y-x is not 0 and the Zero flag is cleared. Then MOVNE checks the zero flag, and only moves 24 into a if the Zero flag is clear.

 

So to answer "how would you use the carry flag with a conditional move?" I ask you: what does the carry flag mean?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!