0

I'm currently studying for an exam and I don't understand the answer to this assembly question: This asm is GCC's output from the C source, except for the jge instruction. What instruction should be there?

link

The correct answer is apparently jle, but to me it seems it should be jge.

For example, if you set a=4 in the C code, you should get 1. Based on my reading of the assembly, this is true for it as well. My logic is as follows:

If (2>=4)
return 0
else
return 1.

I think I am misunderstanding some basic aspect of machine code but I've read references on cmp and jge/jle and I still am confused.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
deersmack
  • 1
  • 1
  • 3
    Please paste the code from the image into the question as formatted text. – Adrian Mole Feb 25 '22 at 17:37
  • 1
    The link is just some code. What is the actual question? – Nate Eldredge Feb 25 '22 at 17:45
  • I thought I made the question clear in the text below the image, the correct answer is jle but based on my understanding of x86 it should be jge. My thought process is listed in the text. – deersmack Feb 25 '22 at 17:49
  • 1
    It seems that all you're missing is that in AT&T syntax the operands are reversed. – prl Feb 25 '22 at 19:43
  • 1
    @deersmack [Why not upload images of code/errors when asking a question?](https://meta.stackoverflow.com/q/285551/995714). To make clear just add a comment on the line you want to address, no need for an image – phuclv Feb 26 '22 at 00:48

2 Answers2

0

The assembly in that image looks wrong. The cmp instruction subtracts 2 from a, but jumps to the return 0 path if the result is positive or zero. Oops.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • So are you saying the way comparison works is cmp(A,B) it does B-A and then jge will jump if B-A>=0? – deersmack Feb 25 '22 at 17:46
  • @deersmack: I'm having a bit of trouble with AT&T syntax. It's a poor fit to x86. But that's how I read it. – Joshua Feb 25 '22 at 17:48
  • Thanks for your response, this seems like the correct way to interpret what my textbook and online resources were saying. I was under the impression that CMP(A,B)...jge meant jump if A>=B. Rather than jump if (B-A)>=0. – deersmack Feb 25 '22 at 17:59
  • 1
    @deersmack: Yeah. Well if it were using intel's own syntax you would be correct. Ugh. – Joshua Feb 25 '22 at 18:18
  • @deersmack: You're correct, it's not just based on the subtraction *result* being positive or zero; remember signed comparison also has to account for OF, not just SF. See https://github.com/HJLebbink/asm-dude/wiki/Jcc. It jumps if `a >= 2`, which is still false if `a` was originally INT_MIN and `a - 2` wrapped to `INT_MAX-1`. But yes, Joshua is correct that's it's a wrong implementation of the C. I wonder if this is from [CS:APP 3e global edition where the practice problems were replaced by incompetent people](https://stackoverflow.com/q/57998998/224132). – Peter Cordes Feb 25 '22 at 22:36
  • @deersmack: But if a subtraction done by `cmp` or `sub` doesn't have signed overflow, then `A>=B` is the same condition as `(B-A) >= 0`. So Joshua's simplification is correct for cases like this `a=5`. If you mentally reverse the operands to `cmp`, then `jge` has the right semantic meaning, like in Intel syntax which the mnemonics were named for: [Assembly - JG/JNLE/JL/JNGE after CMP](https://stackoverflow.com/q/9617877) – Peter Cordes Feb 25 '22 at 22:39
  • @deersmack: https://godbolt.org/z/5ab6sYh9j is actual compiler output from that source (assuming I typed it correctly; in future always post code as text). See [GCC seems to prefer small immediate values in comparisons. Is there a way to avoid that?](https://stackoverflow.com/q/59117603) for why GCC converts the compare against 3 into a compare against 2. The actual compiler output is the same as the image except for using JLE instead of JGE. (I realize now it's *supposed* to be wrong, and the exercise is to fix it. So nvm my earlier comment about CS:APP 3e global edition, the question's ok) – Peter Cordes Feb 25 '22 at 23:15
0

In effect, the logic involved when using branches/jumps is reversed - you are testing for the case where the consequent is being bypassed. Look at this pseudo-code:

if something is true then skip to L2
    do the false case here
    skip to L2 
L1:
    do the true case here
L2:
    continue from here

This page regarding compiler implementation discusses the issues involved in implementing high-level conditional statements in an assembly language.

Schol-R-LEA
  • 436
  • 4
  • 9