2015-03-27 6 views
8

Für eine kurze Hausaufgabe in CS Architecture wurden wir gemacht, um die folgende IA-32 Assembly in C. zu übersetzen Ich habe es richtig übersetzt (so weit ich weiß), aber der Code scheint nichts zu tun Besonders nützlich. Mein Professor gibt uns normalerweise solche Probleme, die am Ende etwas bewirken: unsere letzte Aufgabe war ein bisschen pop_count. Schauen Sie sich den folgenden C-Code an: Hat diese Funktion etwas Sinnvolles? Irgendein Algorithmus vielleicht?Gibt es eine größere Bedeutung für dieses Stück übersetzten Assembler-Code?

Der Code erscheint unten (Ich habe Kommentare zu jeder ASM-Linie hinzugefügt).

// The following variables x, y, z are located at (%ebp) +8, +12, +16 respectively 
// x, y, and z, are scanned from the terminal and passed into the function 

    movl 12(%ebp), %edx     // moves long y to register %edx 
    subl 16(%ebp), %edx     // subtracts longs: y = y - z 
    movl %edx, %eax      // moves long y to register %eax 
    sall $31, %eax      // left shift all bits in long y by 31 places 
    sarl $31, %eax      // arithmetic right shift long y by 31 places 
    imull 8(%ebp), %edx     // multiply longs: unshifted y = y * x 
    xorl %edx, %eax      // XOR operation: shifted y = shifted y^unshifted y 

// The returned value is stored in register %eax 

Das effektive Mitnehmen ist wir z von y subtrahieren, dann füllen jedes Bit mit dem niedrigstwertigen Bit entweder Null oder MAX_UINT zu bilden. Dies wird mit dem Produkt von (y - z) * x XOR-verknüpft und zurückgegeben.

Meine Übersetzung in C:

return (((y - z) << 31) >> 31)^((y - z) * x); 

// In more words: 
    int f; 
    y -= z; 
    f = y << 31;      // These two lines populate all bits with the lsb 
    f = f >> 31;      // Effectively, if y-z is odd: f is ~0; else f is 0 
    y *= x; 
    return y^f; 

// Or, using people logic: 
    y -= z; 
    if (y % 2 == 0) return y * x; 
    return -(y * x) - 1; 

// If the y-z is odd, the result will be: -1 * ((y - z) * x) - 1 
// If the y-z is even, the result will be:    (y - z) * x 

Zur Verdeutlichung ist dieser Teil der HW Zuordnung nicht; Ich habe die Aufgabe abgeschlossen, indem ich den Code übersetzt habe, aber ich möchte wissen, warum er uns diesen-Code gegeben hat.

Antwort

3

Meine Vermutung ist, dass Ihr Professor versuchte zu veranschaulichen, wie Sie Bit-shifting/masking-Operationen verwenden können, um Verzweigungen zu vermeiden. Wenn Sie naiv übersetzen würden, würden Sie einen Verzweigungsbefehl für den bedingten Code verwenden. Verzweigungen können Ihren Code drastisch verlangsamen, besonders wenn sie sich in einer engen Schleife befinden *. Der Assembler-Code und der vorangehende C-Code bewirken, dass eine Bedingung verwendet wird, ob y - z gerade ist oder nicht, aber nur mit arithmetischen Anweisungen.

* Wenn Sie mit dieser Tatsache nicht schon vertraut sind, hat this SO answer eine meiner Lieblingsillustrationen davon.

+0

Das ist ein interessanter Punkt, den Sie gemacht haben. Tatsächlich hat mein Professor erklärt, dass es teilweise die Fähigkeit demonstriert, Logik ohne bedingte Verzweigung durchzuführen. Danke für die Antwort! – SeniorShizzle

Verwandte Themen