Seite 1 von 2

Assembler IF->THEN

Verfasst: 29.08.2014 21:22
von Makke
Hallo zusammen,

ich habe mich en winziges bisschen mit Assembler beschäftigt um zu wissen ob man bestimmte Abfolgen in einer Prozedur mit Assembler beschleunigen kann.

Beispielsweise versuche ich mich an einer einfachen If...Then Abfrage:

Code: Alles auswählen

Define.l d, n, m, i, j, t
m = 5

For n = 1 To m
  
  i = n*2
  j = m
  
  If i > j
    d = 1
  Else
    d = 0
  EndIf
  
Next

EnableASM

For n = 1 To m
  
  MOV eax,n
  MOV ebx,2
  MUL ebx
  MOV i,eax
  CMP m,eax
  JG l_greater
  JL l_less
  greater:
  MOV d,1
  INT 80h ; = Linux unter Windows sollte es wohl INT 21h sein
  less:
  MOV d,0
  INT 80h ; = Linux unter Windows sollte es wohl INT 21h sein
  
  ;Debug i
  ;Debug m
  ;Debug d

Next
Aber diese Verzweigung/Abfrage funktioniert unter Assembler nicht (bzw. nicht so wie sie soll und ich das verstanden habe). Hat da jemand einen Tip.

Re: Assembler IF->THEN

Verfasst: 29.08.2014 21:34
von STARGÅTE
Du fragst gerade nur auf größer und kleiner ab, was ist mit Gleich?
Wenn du zu "greater" springst, dann wird "less" trotzdem ausgeführt.
Was soll "INT 80h" sein?
Wozu ist MOV i, eax wenn du i nicht benutzt?

Hier mal n neue Version:

Code: Alles auswählen

For n = 1 To m
	
	MOV eax, n
	MOV ecx, 2
	MUL ecx
	CMP eax, m
	JLE l_lessequal
	MOV d, 1
	JMP l_ifend
	lessequal:
	MOV d, 0 
	ifend:
	
	Debug d
	
Next

Re: Assembler IF->THEN

Verfasst: 30.08.2014 07:53
von Makke
Hi Stargate,

danke für Deine Modifizierung, leider hatte ich das zuvor so auch schon und es funktioniert nicht. Aber zuerst zu Deinen Fragen:

1. INT 80h (unter Linux, unter WIndow soll es INT 21h sein) ist nach dem Anfängertutorial das "End" für Assembler (ein Signal das dem Code sagt hier ist ende).
2. das "i" habe ich für mich zu Debug Zwecken eingebaut.

Hier mal der Code wie ich begonne habe:

Code: Alles auswählen


Define.l d, n, m, i, j, t

m = 5
t = ElapsedMilliseconds()

EnableASM

For n = 1 To m
  
  MOV eax,n
  MOV ebx,2
  MUL ebx
  MOV i,eax
  MOV ecx,m
  MOV j,ecx
  CMP eax,j
  JE  l_equal
  JG  l_greater
  JL  l_less
  equal: 
  MOV d,0
  JMP l_finish
  greater: 
  MOV d,1
  JMP l_finish
  less: 
  MOV d,-1
  finish:
  
  Debug Str(i)+"<->"+Str(j)+"="+Str(d)
  
Next

Debug "ASM Time: "+Str(ElapsedMilliseconds()-t)

DisableASM

t = ElapsedMilliseconds()

For n = 1 To m
  
  i = n*2
  j = m
  
  If i = j
    d = 0
  ElseIf i > j
    d = 1
  Else
    d = -1
  EndIf
  
Next

Debug "PB Time: "+Str(ElapsedMilliseconds()-t)
Aber es funktionierte nicht, deswegen habe ich das ganze verkürzt um der Sache auf den Grund zu kommen. Bei der ersten Konstellation kommt bei mir immer d=1 raus, bei Deinem Code übrigens auch.

Könnte es evtl. an Linux liegen, das da ein Bug ist ?

Re: Assembler IF->THEN

Verfasst: 30.08.2014 08:04
von ts-soft
Das mit dem INT 80h oder noch schlimmer 21h würde ich aber lassen. Das sind IMHO interrupts, die so
nicht mehr unterstützt werden, zumindest im UserSpace.
Softwareinterrupt

Re: Assembler IF->THEN

Verfasst: 30.08.2014 13:06
von STARGÅTE
@Makke:

Dein Code funktioniert bei mir.
Beachte bitte das du den ASM-Code für x86 geschrieben hast, der nicht unter x64 funktioniert.

Re: Assembler IF->THEN

Verfasst: 30.08.2014 14:42
von TheCube
Unter DOS hat man "früher" sein Programm so verlassen:

Code: Alles auswählen

mov ah,4ch  ; Fkt 4ch nutzen
int 21h  ;Interrupt auslösen 
Eingebettet in PB-Code also nicht zu empfehlen .... INTs also weglassen,
werden eh (wie ts-soft schon schrieb) nicht funktionieren.

Re: Assembler IF->THEN

Verfasst: 30.08.2014 16:29
von Helle
Seit den letzten PB-Versionen (speziell 64-Bit) gilt für ASM-Code: Debugger ausschalten!!! Lasst euch Ergebnisse sonstwie anzeigen (und wenn es der Messagerequester ist). Debug zerstört mittlerweise Register und Flags. Ich hatte da schon etliche Beispiele (z.B. auch XMM-Register).
Ansonsten: Nutzt den (mehr oder weniger) unabhängigen FASM-Code, also "! Instruction...").
INT in Windows-Programmen geht natürlich nicht.

Re: Assembler IF->THEN

Verfasst: 31.08.2014 08:46
von Makke
@Stargate: danke für den Tip 32bit<->64bit, aber daran lag es nicht

@Helle: danke für den Tip mit dem Debugger, daran lag es tatsächlich, wenn ich den Debugger anlasse, kommt kein Ergebnis bzw. immer nur 1 heraus, wenn ich den Debugger ausschalte (und die Ergebnisse in eine Datei speichere) dann kommen die richtigen Ergebnisse.

Re: Assembler IF->THEN

Verfasst: 02.09.2014 09:48
von Martin66119
Guten Tag,

ich habe mal auf meinen Netbook den Code getestet.

Statt der beiden Debugzeilen habe ich jeweils
MessageRequester("Zeit",Str(ElapsedMilliseconds()-t), #PB_MessageRequester_Ok) eingefügt.

In Testcode habe ich m= 100000000

Ergebnis:
ASM-Schleife = 2099 ms
PB-Schleife = 1107 ms

Der Debugger ist ausgeschaltet.

Grüße

Re: Assembler IF->THEN

Verfasst: 02.09.2014 16:34
von Danilo
Martin66119 hat geschrieben:Statt der beiden Debugzeilen habe ich jeweils
MessageRequester("Zeit",Str(ElapsedMilliseconds()-t), #PB_MessageRequester_Ok) eingefügt.

In Testcode habe ich m= 100000000

Ergebnis:
ASM-Schleife = 2099 ms
PB-Schleife = 1107 ms
Der ASM-Code ist ja auch nicht optimiert, eher ein erster Versuch einer 1:1 Übersetzung.