理解C函数调用生成的程序集
我正在试图了解这个汇编代码的情况。我通过键入理解C函数调用生成的程序集,c,assembly,C,Assembly,我正在试图了解这个汇编代码的情况。我通过键入gcc-O1-S calc.c创建了它,它生成了一个calc.S汇编文件 有人能逐行解释一下(在calc.c中的加法和乘法)发生了什么吗 原始C代码是: .file "calc.c" .text .globl calc .type calc, @function calc: pushl %ebp movl %esp, %ebp
gcc-O1-S calc.c
创建了它,它生成了一个calc.S
汇编文件
有人能逐行解释一下(在calc.c
中的加法和乘法)发生了什么吗
原始C代码是:
.file "calc.c"
.text
.globl calc
.type calc, @function
calc:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 16(%ebp), %ecx
leal (%edx,%edx,2), %edx
movl 12(%ebp), %eax
leal (%edx,%eax,2), %eax
movl %ecx, %edx
sall $4, %edx
subl %ecx, %edx
addl %edx, %eax
popl %ebp
ret
.size calc, .-calc
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
好的,现在它做了一些事情,我将为您注释它
int calc(int x, int y, int z)
{
return 3*x + 2*y + 15*z;
}
您已经创建了一个未使用的嵌套函数,该函数已经过优化,因此不在程序集列表中。删除
main
函数,然后重试。可能您键入了。全局计算
对不起。我更正了代码。(组装和c)请改进标题,以便对未来的网站访问者有用。当前的标题非常模糊,有相同问题的人不会意识到这是同一个问题。此外,这似乎不是一个特定的编程问题。您遇到的编程问题是什么?理解这个计算函数是解决问题的方法吗?回答得很好!一些附加信息:C将函数参数按相反顺序推送到堆栈上,int
s有4个字节长。我做了一些欺骗,并从对它们所做的操作中推断出它们的含义。您还可以查看cdecl
调用约定,查看它们基于偏移量的参数索引。leal(x,y,z),w
转化为w=x+y*z
令人惊讶的是16z-z
比15z
更受欢迎。真棒的问答!移位和加法/减法是非常“便宜”的运算,而乘法在处理时间上是“昂贵”的。将一个数字向左移动相当于乘以2,现代编译器经过优化以有效处理常见操作。例如,您会发现,10x
可能会转换为2x+8x
,实现为x
calc:
pushl %ebp ; \
movl %esp, %ebp ; / set up basic stack frame
movl 8(%ebp), %edx ; load x
movl 16(%ebp), %ecx ; load z
leal (%edx,%edx,2), %edx ; calculate x + 2 * x
movl 12(%ebp), %eax ; load y
leal (%edx,%eax,2), %eax ; calculate (x + 2 * x) + (2 * y)
movl %ecx, %edx ; make a temp copy of z
sall $4, %edx ; calculate z * 16
subl %ecx, %edx ; calculate (z * 16) - z
addl %edx, %eax ; calculate final sum
popl %ebp
ret