ich diese C-Funktion zusammengestellt:Warum gibt es drei wichtige Anweisungen für diesen IA32-Assemblercode?
int calc(int x, int y, int z) {
return x + 3*y + 19*z;
}
Und ich habe dies in calc.s, und ich bin mit Anmerkungen versehen, was geschieht:
.file "calc.c"
.text
.globl calc
.type calc, @function
calc:
pushl %ebp //Save paramaters
movl %esp, %ebp //Move stack pointer into %ebp
movl 12(%ebp), %eax //Move y into %eax
movl 16(%ebp), %ecx //Move z into %ecx
leal (%eax,%eax,2), %eax //%eax = 3*y
addl 8(%ebp), %eax //%eax = x+3y
leal (%ecx,%ecx,8), %edx // ?
leal (%ecx,%edx,2), %edx // ?
addl %edx, %eax //%eax = (x+3*y)+(19*z)
popl %ebp //Pop the previous pointer
ret
.size calc, .-calc
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
Ich verstehe die letzten zwei leal Anweisungen alles auf. Warum benötigen Sie zwei leal Anweisungen für 19 * z, während 3 * y in einer Anweisung ausgeführt wird.
See Die Antwort von Sergey - lea kann nur mit 2, 4 oder 8 multipliziert werden. –
Die allgemeine Antwort ist, dass LEA-Anweisungen wie Multiply-and-Add-Befehle aus kleinen Konstanten 1,2,4,8 agieren. Indem man sie verwendet, kann man in einigen Maschinenbefehlen mit verschiedenen Werten multiplizieren, und das ist schneller als mit einer echten Multiplikationsanweisung. –