web-dev-qa-db-fra.com

instruction IF complexe dans l'assemblage

Comment dois-je écrire une telle instruction if dans l'assembly?

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

Plateforme: machine Intel 32 bits, syntaxe NASM.

Mise à jour

Pour les types et valeurs de variables, utilisez tout ce qui est plus facile à comprendre. Les entiers fonctionneraient très bien pour moi, je suppose.

14
user1960660

Dans un assemblage générique, ce sera essentiellement quelque chose comme ça (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

S'il n'y a pas de faux bit, il peut être simplifié pour:

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

nextinstr:
    ; carry on
20
paxdiablo

Vous devrez diviser l'instruction if en une série de comparaisons et de sauts. De la même manière qu'en C vous pourriez écrire:

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
}

Ce qui brise l'expression complexe en parties constitutives, votre asm fera de même, bien que vous puissiez l'écrire plus proprement en asm en sautant sur les parties qui sont toujours pertinentes.

En supposant que a, b et c vous soient transmis sur la pile (s'ils ne les chargent pas ailleurs évidemment)

        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:
10
Flexo