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 can't do it without jumps because && is a short-circuit operator.

```
    XOR ecx, ecx
    MOV eax, <value of A>
    MOV ebx, <value of B>
    TEST eax, eax
    JZ testDone
    TEST ebx, ebx
    JZ testDone
    INC ecx
testDone:
    ...

```