Question: How can I code the C '&&' operator in x86? For example:

```
int a = ...
int b = ...
int c = a && b;

```

What would be the equivalent of the last line in x86?

EDIT: I want to do the above without any jumps.

EDIT: g++ generates this, but I don't understand it:

```
testl   %edi, %edi
setne   %dl
xorl    %eax, %eax
testl   %esi, %esi
setne   %al
andl    %edx, %eax

```

Answer: 
Here is how GCC implements it at `-O3`.

```
    movl    8(%esp), %edx  ;; load argument into edx
    xorl    %eax, %eax     ;; eax = 0
    movl    4(%esp), %ecx  ;; load other argument into ecx
    testl   %edx, %edx     ;; Is EDX nonzero?
    setne   %al            ;; al = 1 if Z = 0
    xorl    %edx, %edx     ;; EDX = 0
    testl   %ecx, %ecx     ;; Is ECX nonzero?
    setne   %dl            ;; dc = 1 if Z = 0
    andl    %edx, %eax     ;; edx &= eax

```

Note that this code does not short-circuit; this is because in this case GCC can prove that there are no side effects from the second argument. If the second argument has side-effects, you must implement it using jumps. For example:

```
int test(int *a, int *b) {
  return (*a)++ && (*b)++;
}

```

becomes:

```
test:
        pushl   %ebx            ;; save ebx
        movl    8(%esp), %eax   ;; load a into eax
        movl    12(%esp), %ecx  ;; load b in to ecx
        movl    (%eax), %edx    ;; *a -> edx
        leal    1(%edx), %ebx   ;; ebx = edx + 1
        movl    %ebx, (%eax)    ;; *a <- ebx
        xorl    %eax, %eax      ;; eax = 0
        testl   %edx, %edx      ;; if the old value of *a was 0...
        je      .L2             ;; jump to the end
        movl    (%ecx), %eax    ;; *a -> eax
        testl   %eax, %eax      ;; does *a = 0?
        leal    1(%eax), %edx   ;; edx = *a + 1 (does not set flags!)
        setne   %al             ;; al = 1 if Z (ie, if a = 0 at the testl above)
        movl    %edx, (%ecx)    ;; save edx to *a (increment *a)
        movzbl  %al, %eax       ;; zero-extend al to eax
.L2:
        popl    %ebx            ;; restore ebx
        ret                     ;; return

```
You are right, the obvious implementation uses branches. My original idea was to convert each operand into either 0 or -1 via a sign-extending bit shift, and then using the bitwise and instruction, but [gcc(1)](http://en.wikipedia.org/wiki/GNU_Compiler_Collection) has reminded me of the *setxy* x86 instruction, so that seems easier.

The following function implements: `int f(int a, int b) { return a && b; }`

```
.text
.globl f
f:
  cmpl   $0, 4(%esp)
  setne  %dl
  cmpl   $0, 8(%esp)
  setne  %al
  movzbl %al, %eax
  andl   %edx, %eax
  ret

```

As it happens, the correct *value* for the expression can be computed without branches or jumps, but by defining my implementation as a function I'm kind of cheating because it forces both operands to be evaluated in order to make the function call, at which point the function does no harm by *reading* both operands without the short-circuit because the parameters are known to be copies.

But for open code, whether this can be done without a jump depends entirely on whether the right-hand operand can be evaluated without side-effects. So, it depends on the type. Imagine the case where the right hand operand is a function call, perhaps an I/O op or a kernel system call. The generated code cannot evaluate it *at all* if the left hand operand is false, and I don't see how that could be done without a branch or jump.

It's interesting that gcc -O (which generates similar code) seems to violate C99 6.5.13(4) which states flatly *"If the first operand compares equal to 0, the second operand is not evaluated."* In the case of assembling *f()* it apparently decides that since a value parameter can't have side effects, then there is no harm in compiling code contrary to C99's literal specification.