Multiply: .globl Multiply /* Mantisse der ersten Zahl laden (%eax) */ movl 4(%esp), %eax /* Mantisse der zweiten Zahl laden (%ebx) */ movl 8(%esp), %ebx /* Mantissen miteinander multiplizieren (%ax) */ imulw %bx, %ax andl $0x0000ffff, %eax /* Exponent der ersten Zahl laden, Vorzeichenbit entfernen (%ebx) */ movl 4(%esp), %ebx andl $0x7fff0000, %ebx /* Exponent der zweiten Zahl laden, Vorzeichenbit entfernen (%ecx) */ movl 8(%esp), %ecx andl $0x7fff0000, %ecx /* Exponenten miteinander addieren, in Ergebnis einfuegen (%eax) */ addl %ecx, %ebx orl %ebx, %eax /* Vorzeichen per XOR miteinander verknuepfen (%ebx) */ movl 4(%esp), %ebx xorl 8(%esp), %ebx /* Neues Vorzeichen in Ergebnis einfuegen (%eax) */ andl $0x800000, %ebx orl %ebx, %eax /* Ruecksprung */ ret
int func(int v) { int i; for (i = 0; i*i < v; i++); return i; }
Einspruch: Bei einer for-Schleife wird ja schon vor dem Betreten die Bedingung geprüft, das passiert im Assembler-Code da aber nicht. Ich hätte da so was:
int func(int v) { int i; for (i = 0;; i++) { i *= i; if (i >= v) break; } return i; }
Die letzte Variante ist falsch, weil die Multiplikation mit %eax ist und %eax nicht zwischengespeichert wird. Dementsprechend ist die erste Variante richtig.
Noch etwas: Ich glaube die Ints müssen unsigned Ints sein.
unknown: pushl %ebp movl %esp, %ebp pushl $0 .L2: movl -4(%ebp), %eax imull -4(%ebp), %eax cmpl 8(%ebp), %eax jb .L4 jmp .L3 .L4: incl -4(%ebp) jmp .L2 .L3: movl -4(%ebp), %eax movl %ebp, %esp popl %ebp ret
Funktionstabelle der Form: x_3 x_2 x_1 x_0 | c y_3 y_2 y_1 y_0
Mit Symmetriediagrammen vereinfacht: