15

How should I write such an if statement in assembly?

if ((a == b AND a > c) OR c == b) { ...

Platform: Intel 32-bit machine, NASM syntax.

Update

For variable types and value, use whatever is more easy to understand. Integers would works fine for me, I guess.

nrz
  • 10,435
  • 4
  • 39
  • 71

2 Answers2

25

In generic assembly, it will be basically something like this (a in ax, b in bx, c in cx):

    cmp  bx, cx
    jeq  istrue
    cmp  ax, cx
    jle  isfalse
    cmp  ax, bx
    jeq  istrue
isfalse:
    ; do false bit
    jmp  nextinstr
istrue:
    ; do true bit

nextinstr:
    ; carry on

If there's no false bit, it can be simplified to:

    cmp  bx, cx
    jeq  istrue
    cmp  ax, bx
    jne  nextinstr
    cmp  ax, cx
    jle  nextinstr
istrue:
    ; do true bit

nextinstr:
    ; carry on
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • I think it's good to point out here that in a language like C, the left side of the AND and OR would be evaluated first, and the right side may be skipped. If you want to write assembly for an if statement that matches C logic, you would have to change up the order here. – jowo Jul 11 '22 at 03:16
11

You will need to break the if statement into a series of comparisons and jumps. In the same way that in C you could write:

int test = 0;

if (a == b) {
  if (a > c) {
    test = 1;
  }
}

// assuming lazy evaluation of or:
if (!test) {
  if (c == b) {
    test = 1;
  }
}

if (test) {
  // whole condition checked out
}

Which breaks the complex expression into constituent parts your asm will do likewise, although you can write it more cleanly in asm by jumping to the parts that are still relevant.

Assuming a, b and c are being passed to you on the stack (if they're not load them from elsewhere obviously)

        mov     eax, DWORD PTR [ebp+8] 
        cmp     eax, DWORD PTR [ebp+12] ; a == b?
        jne     .SECOND                 ; if it's not then no point trying a > c 
        mov     eax, DWORD PTR [ebp+8]
        cmp     eax, DWORD PTR [ebp+16] ; a > c?
        jg      .BODY                   ; if it is then it's sufficient to pass the
.SECOND:
        mov     eax, DWORD PTR [ebp+16]
        cmp     eax, DWORD PTR [ebp+12] ; second part of condition: c == b?
        jne     .SKIP
.BODY:
        ; .... do stuff here
        jmp     .DONE
.SKIP:
        ; this is your else if you have one
.DONE:
Flexo
  • 87,323
  • 22
  • 191
  • 272