1

Can someone please explain why the following C code generates a jg jump statement in assembly rather than jle?

#include <stdio.h>

  int foo(int a, int b)
  {
    if (a<=b) return a;
      else return b;
  }//end foo

 int main()
 {
  return  foo(1,2);
 }//end main



Dump of assembler code for function foo:
0x080483db <+0>:    push   %ebp
0x080483dc <+1>:    mov    %esp,%ebp                
0x080483de <+3>:    mov    0x8(%ebp),%eax       # eax = a
0x080483e1 <+6>:    cmp    0xc(%ebp),%eax       # a - b
0x080483e4 <+9>:    jg     0x80483eb <foo+16>   # my interpretation "if a > b goto 16"  ***Why does this not use JLE???***
0x080483e6 <+11>:   mov    0x8(%ebp),%eax       # return a 
0x080483e9 <+14>:   jmp    0x80483ee <foo+19>   # goto 19
0x080483eb <+16>:   mov    0xc(%ebp),%eax       # return b
0x080483ee <+19>:   pop    %ebp                 
0x080483ef <+20>:   ret   
dsmits
  • 11
  • 1
  • Because that's how it decided to lay out the branches. Perhaps according to some heuristic that guesses that `<=` is more likely than `>` (because it includes the `==` case), and lays out the code to have fewer taken branches on average. – Peter Cordes Mar 02 '18 at 03:14
  • Compiler's has decided in this case to test the opposite condition and do the jump to get to the first leg of the `if`. Nothing wrong with it. In this case, it's 50-50 as far as which way is less or more efficient code. But in some cases, it does make more of a difference and the compiler picks what it thinks is best. – lurker Mar 02 '18 at 03:15
  • Took me a while to find it again, but there was already a big Q&A about ordering if `if`/`else` blocks vs. how the compiler chooses to lay them out. Most of that applies even at `-O0` (no optimization) like you're using. – Peter Cordes Mar 02 '18 at 03:18
  • It returns b if a > b else it returns a, so what's the problem? It does exactly what you asked for. – user253751 Mar 02 '18 at 03:30
  • No problem, just trying to understand how the compiler works. I guess the piece I didn't understand was where the "equal to" of my C statement in assembly. I think when the compare statement occurs this would evaluate whether a and b were equal and return a. I'm new to assembly so this isn't very intuitive to me yet. Thanks for the help! – dsmits Mar 02 '18 at 03:43
  • `jg` is the opposite condition to `jle`, so effectively the compiler decided to make asm that looked more like `if(a>b) return b; else return a;`. Note that [`jg` is a synonym for `jnle` (jump if not less or equal)](https://github.com/HJLebbink/asm-dude/wiki/Jcc), so there's the semantic meaning you were looking for. And BTW, AT&T syntax makes the compares look "backwards". Intel syntax (`objdump -drwC -Mintel`, or in GDB: `set disassembly-flavor intel`) will have `cmp eax, ecx` / `jg` to jump if `eax > ecx`, for example. So the mnemonics match the sense of the compare. – Peter Cordes Mar 02 '18 at 04:10
  • Actually I wrote that backwards. The compiler did lay out your branches the same as your C source, with the `if` clause as the fall through. Thus it needs a conditional branch to the `else` block. Hence the `jnle`. – Peter Cordes Mar 02 '18 at 04:43

0 Answers0