Entwickler-Ecke

Algorithmen, Optimierung und Assembler - (ASM) Assembler overflow und jumps?


white-desert - So 27.01.08 00:07
Titel: (ASM) Assembler overflow und jumps?
Hallo,
komme einfach nicht weiter: Zum 1-Byte register AL wird soviel dazuaddiert, dass ein overflow entsteht (240+33).
Per JO (Springe wenn Overflow Flag gesetzt ist) kann man (soviel ich weiss) zu einem Label springen, wenn das OVERFLOW-Flag gesetzt ist. Aber bei mir gibt diese Funktion immer 0 zurueck, der Code unter @overflow wird nicht ausgefuehrt, NUR der unter @nooverflow :-(


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
function machmal:Integer;
asm
  { eax = 0 }
  xor eax, eax

  { al = 240 }
  mov al, 240

  { 240+33 > 255!!! --> overflow???????????? }
  add al, 33

  { wenn overflow dann geh zu overflow }
  jo  @overflow

  { wenn nicht, dann eben nicht :-)  }
  jmp @nooverflow


  @overflow:
    mov eax, 255

  @nooverflow:
    mov eax, 0
end;


was mache ich falsch?
dankeschoen!


Allesquarks - So 27.01.08 01:01

Hm kann es sein, dass overflow nicht das richtige Flag ist. Müsste nachschauen, aber kann es sein, dass das überläufe bei Zahlen mit Vorzeichen angibt. Versuch das ganze doch mal mit dem carry Flag (jc @@...).


Reinhard Kern - So 27.01.08 09:57
Titel: Re: (ASM) Assembler overflow und jumps?
user profile iconwhite-desert hat folgendes geschrieben:
.... Aber bei mir gibt diese Funktion immer 0 zurueck, der Code unter @overflow wird nicht ausgefuehrt, NUR der unter @nooverflow :-(


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
function machmal:Integer;
asm
  { eax = 0 }
  xor eax, eax

  { al = 240 }
  mov al, 240

  { 240+33 > 255!!! --> overflow???????????? }
  add al, 33

  { wenn overflow dann geh zu overflow }
  jo  @overflow

  { wenn nicht, dann eben nicht :-)  }
  jmp @nooverflow


  @overflow:
    mov eax, 255

  @nooverflow:
    mov eax, 0
end;


was mache ich falsch?
dankeschoen!


Nach @overflow wird sofort @nooverflow ausgeführt, die Unterscheidung durch Jump ist damit wirkunglos. Es müsste heissen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function machmal:Integer;
asm
      xor   eax, eax  { eax = 0 }
      mov   al, 240
      add   al, 33
      jo    @overflow
      mov   eax, 0
      jmp   @done
@overflow:
      mov   eax, 255
@done:
end;


Gruss Reinhard


BenBE - So 27.01.08 18:55

Geht übrigens auch eleganter ...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function machmal:Integer;
asm
//      xor   eax, eax  { eax = 0 }
      mov   al, 240
      add   al, 33

      setc  al //OVerflow-Flag abfangen (durch Carry repräsentiert)
      neg   al //Vorzeichen (Ones Complement) ändern. (Wenn True\False wie unten vorgeschlagen, entfällt der hier)

      movsx eax, eax //Wenn wirklich Integer benötigt, ansonsten weglassen
end;


Ach ja: Im Normalfall: Wenn Du Boolean zurückgeben willst, gibt 0 für False und 1 für True zurück. Gibt ansonsten arge Probleme bei einigen Dingen was Delphi optimiert, weil der Compiler bei Array[Boolean] of ... z.B. einfach den Index mit der Größe des Datentyps multipliziert, was zu sehr merkwürdigen Fehlern führt (die auf normale Art und Weise nicht reproduzierbar sind).


white-desert - Di 29.01.08 10:14

user profile iconAllesquarks hat folgendes geschrieben:
Hm kann es sein, dass overflow nicht das richtige Flag ist. Müsste nachschauen, aber kann es sein, dass das überläufe bei Zahlen mit Vorzeichen angibt. Versuch das ganze doch mal mit dem carry Flag (jc @@...).

Ja. Ich hab ein falsche Flag genommen. Das Carry-Flag gibt in Wirklichkeit den Ueberlauf an.
Danke an alle,
Danke Allesquarks :-)