ASM - geht das auch schneller?

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

ASM - geht das auch schneller?

Beitrag von Leonhard »

Ich schreibe im moment an einem Compiler, der mir folgenden Code

Code: Alles auswählen

lVar = 10 + 8 * 2 + (4 == 4)
in den Assemblercode

Code: Alles auswählen

    MOV eax, 4
    ; == ('eax', '4')
    CMP  eax, 4
    XOr  eax, eax
    JNE   if.ElseIf.0
    MOV  eax, 1
    if.ElseIf.0:
    ADD eax, 26
    MOV dword[esp + 0], eax
optimiert und übersetzt.
Ich weiß, das ich (4==4) auch optimieren könnte (zu 1 bzw. true), aber ich möchte erst die Bedingung in Assembler übersetzen (was hier auch funktioniert).

Geht das auch schneller?
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Habe zwar schon etliche Hefeweizen inner Birne, aber was soll denn das CMP? XOR eax,eax setzt auf jeden Fall das Zero-Flag. Allgemein könnte man es so machen (True=1; False =0):

Code: Alles auswählen

  ;(4 == 4) ---> (x == y)
    MOV eax,x
    SUB eax,y
    JZ If.ElseIf.True 
    XOR eax,eax
    JMP If.ElseIf.False
    If.ElseIf.True:
    INC eax
    If.ElseIf.False:
    ADD eax, 26 
    MOV dword[esp + 0], eax    
Gruss
Helle
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Ich versteh jetzt nicht den Unterschied zwischen CMP und SUB.
Ich kann doch SUB nicht immer verwenden, oder? Und welcher ist schneller?
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

In deinem Code ist das CMP Muster ohne Wert, denn die Flags, die du zum Sprung mit JNE auswerten willst, werden durch das XOR neu gesetzt. Der Sprung wird nie ausgeführt, du erhälst immer wahr, egal was du vergleichst. Es funktioniert, wenn du XOR EAX,EAX in MOV EAX,1 änderst. Aber: Du hast dann 2x MOV, um die (Boolschen-)Werte zu setzen. Und jetzt kommt´s mit der Geschwindigkeit: Nicht nur die Anzahl der Befehle machts, sondern auch wie lang sein Opcode ist. Lieber einen Befehl mehr, dafür aber kurz und knackig (Stichwort Pipelining). Jeder "MOV Wert"-Befehl ist 5 Bytes lang, XOR EAX,EAX und die Short-Sprünge jeweils 2 Byte und INC EAX ist gar nur 1 Byte lang. Deshalb habe ich SUB verwendet, weil ich so INC und XOR verwenden kann. Übrigens, die Short-Sprünge benötigen auch nur einen Taktzyklus; sind also keineswegs Zeit-Fresser.

Gruß
Helle
Antworten