-5

I wondered why gcc assembler use negative form of conditions instead of positive one. Suppose that we have following C code:

if (x == 10)
{
  x ++;
}

y ++;

When I use gcc to compile and produce object file, the result of assembly code in PowerPC assembly is as follows:

  20:   2c 00 00 0a     cmpwi   r0,10
  24:   40 82 00 10     bne 34 <main+0x34>
  28:   81 3f 00 08     lwz r9,8(r31)
  2c:   38 09 00 01     addi    r0,r9,1
  30:   90 1f 00 08     stw r0,8(r31)
  34:   81 3f 00 0c     lwz r9,12(r31)
  38:   38 09 00 01     addi    r0,r9,1
  3c:   90 1f 00 0c     stw r0,12(r31)

The assembly uses bne while I used equal == in my C code.

EDIT 1:

I know that the code is working perfectly. But I means why assembler use negative form not positive one.

EDIT 2: I am using the compiler with level 0 optimizer and we know that, it is not intelligent. My means from question is that, why assembler couldn't produce assembly such a below:

cmpi x, 10
beq label1
b label2

label1:
add x, x, 1
label2:
add y, y, 1

Could any one please explain what happens?

Thanks in advance.

Hossein Mobasher
  • 4,382
  • 5
  • 46
  • 73
  • This is the design choice of the compiler programmers. They've made it for their reasons, while seeing the whole picture. – Eugene Sh. Aug 19 '15 at 15:17
  • 3
    The generated code doesn't make sense. Since I trust compilers, the logical conclusion is that *you*'ve made a mistake... Please re-check your code and post. – Karoly Horvath Aug 19 '15 at 15:23
  • Please read the EDIT – Hossein Mobasher Aug 19 '15 at 15:24
  • 4
    No, the code is incorrect. `y ++;` should be executed unconditionally. You've probably made an error while "copy-pasting" the generated assembly... – Karoly Horvath Aug 19 '15 at 15:25
  • Oh, Yes. That's my fault in copy-pasting. Sorry. I corrected it. – Hossein Mobasher Aug 19 '15 at 15:27
  • My question is why assembler uses the negative form? – Hossein Mobasher Aug 19 '15 at 15:27
  • 1
    It's still incorrect. – Karoly Horvath Aug 19 '15 at 15:28
  • I've edited the code. Thanks for your hints. – Hossein Mobasher Aug 19 '15 at 15:30
  • As you are asking about the **compiler's** output, why not post the compiler generated code, instead of your hand-written code? – too honest for this site Aug 19 '15 at 15:30
  • The compiler can do absolutely anything it wants as long as the program functions as described (by the C code) what would you have the assembly output for `if(!!!!!!!!!!!someBool){doSomething();}` be? – Grady Player Aug 19 '15 at 15:32
  • 1
    Regarding the question: Instead of just asking, you should think yourself and try to follow both, the generated code and the one you **think** had to be generated. Then you will see **why** the compiler generated the code as it did. – too honest for this site Aug 19 '15 at 15:32
  • Could be an assignment/homework. – too honest for this site Aug 19 '15 at 15:33
  • Why should it use exactly what's written in your code? The optimizer can do even more surprise things. And why don't add the tag for that architecture? – phuclv Aug 19 '15 at 15:35
  • @Olaf: I've post the generated code. I use the handwritten one to show the problem simple. – Hossein Mobasher Aug 19 '15 at 15:36
  • @LưuVĩnhPhúc That is common for all architecture assemblers. – Hossein Mobasher Aug 19 '15 at 15:37
  • All you can vote down for my question. But the question is really important for me and that is not assignment or homework. I can't find anything on the web for my own and I forced to explain my problem on stackoverflow. – Hossein Mobasher Aug 19 '15 at 15:39
  • It shows little research, which is a valid reason for DV. A simple analysis will give you the answer. And it is irrelevant if it is important for _you_ (sorry to tell you the truth). But perhaps complaining about the bad downvoters on SO is easier, than reading the comments and thinking about them. – too honest for this site Aug 19 '15 at 15:42
  • @HosseinMobasher I'm not going to comment on the downvotes. But I am going to recommend to you Olaf's suggestion: If you were the compiler, how would you translate this code to assembly? Write it down, and see. – ArjunShankar Aug 19 '15 at 15:46
  • @Olaf Thanks for your comment. I read all of them and do what they want (In some cases). But I thought about my problem much more and I forced to ask the question here. – Hossein Mobasher Aug 19 '15 at 15:46
  • @ArjunShankar: The assembler can do that with equal comparison instruction, but preferred to use negated form. We can do that with the following code: `cmpwi r0, 10 --- beq label1 --- b label2 --- label1: add to x --- label2: add to y ` – Hossein Mobasher Aug 19 '15 at 15:48
  • 2
    So... you think having two branches is better than having one branch? – ArjunShankar Aug 19 '15 at 15:52
  • I hope that answers your question ;) – ArjunShankar Aug 19 '15 at 15:52
  • @ArjunShankar Assembler with optimizing level 0 is not intelligent. So, producing more that one branch is not impossible. – Hossein Mobasher Aug 19 '15 at 15:54
  • 1
    @HosseinMobasher this is simply too simple an 'optimization' for a compiler to skip. It involves no cost at all. Anyway, I see your question has now been answered to your satisfaction. Cheers. – ArjunShankar Aug 19 '15 at 15:56
  • The C standard does not define optimization levels. The compiler is allowed to do anything it wants as long as the generated code follows the abstract machine. And why should the compiler generate complete superfluous code, whcih does not even help perserving the structure more than better code? – too honest for this site Aug 19 '15 at 15:57

1 Answers1

1

The reason the the negative form is simple : branching is the opposite of an if. Branching means "skip if", while if means "execute if". So, for an assembly with a conditional branching model, all the if conditions will be negated to translate to a single branch. For an if+else, it doesn't matter because the two can be swapped, but usually the negation is preserved.

Negating is the intuitive thing here ; take your example :

if (x == 10)
{
    x++;
}
y++;

When you "run" the code in your head, what do you do ? You look at the condition, and check if it is true. If it is, you do x++, then y++. If it isn't, you jump directly to y++. In other words, you jump (branch) to y++ if the condition is false ; you intuitively negate the condition.

ElderBug
  • 5,926
  • 16
  • 25
  • Thanks for your answer. Could you please give me such a reference to read more about that? – Hossein Mobasher Aug 19 '15 at 15:41
  • @HosseinMobasher There isn't really a reference, it's just that the logic of a branch is the opposite of the logic of a 'if', so you have to negate the condition do to the same thing. Take a notepad and try to do a simple 'if' using a branch without negating condition. You will see that you need more than one branch, but you can do it in a single branch if you negate. – ElderBug Aug 19 '15 at 15:48
  • Thanks for your reply. I used assembler with optimizing level 0. So, I thought that the assembler do that with more than one branch. – Hossein Mobasher Aug 19 '15 at 15:53
  • @ElderBug you can really improve this answer by editing your above comment into it. And grabbing the OP's handwritten code (with two branches, in a comment below the question now) and putting that in there too. – ArjunShankar Aug 19 '15 at 15:55
  • @HosseinMobasher: The assembler does not optimize (in general)! It is the C compiler which optimizes! – too honest for this site Aug 19 '15 at 15:59
  • Yes, I mean the compiler. Sorry for that. – Hossein Mobasher Aug 19 '15 at 16:00