我编译这个C函数:为什么这个IA32汇编代码有三条leal指令?
int calc(int x, int y, int z) {
return x + 3*y + 19*z;
}
而且我在calc.s得到这个,而我注释发生了什么事:
.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
我明白了一切到最后两个莱亚尔指令。为什么你需要两个19 * z的leal指令,而3 * y是在一个指令中完成的。
见谢尔盖的答案 - lea只能乘以2,4或8. –
一般的答案是,LEA指令的作用类似于来自小常量1,2,4,8的乘加指令。通过使用它们,可以在几条机器指令中乘以不同的值,这比使用真正的乘法指令更快。 –