从汇编代码到 C 代码
Going from Assembly to C code
这是 AT&T 语法
.global bar
.type bar, @function
bar:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl , %esp
movl 8($ebp), %ebx
movl , %eax
cmpl , %ebx
jle .L3
leal -1(%ebx), %eax //subtracts 1 from ebx and stores into eax
movl %eax, (%esp) //putting on stack frame
call bar //recursive call
addl %ebx, %eax // adds %ebx and %eax
.L3 //returns %eax
addl , %esp
popl %ebx
popl %ebp
ret //end of bar
所以我认为这里发生的基本上是检查 %ebx 是否 <= 1,如果是,它 return 是一个。否则,它用 x--;
调用 bar
所以我的 C 代码是:
int bar (int x)
{
if (x<= 1)
return 1;
else
return x + bar(x-1);
}
这里的递归调用真的把我骗了。我意识到它用新的 %eax 寄存器调用 bar(基本上变成 x-1)。那么它只是 return 数字的总和吗?
int bar(int x)
{
if (x<= 1)
return 1;
else
return x+bar(x-1);
}
按升序将 x 加到 1
我会这样注释它:
bar: // bar() {
pushl %ebp // function prologue
movl %esp, %ebp //
pushl %ebx //
subl , %esp //
movl 8($ebp), %ebx // %ebx = x
movl , %eax // %eax = 1
cmpl , %ebx // if (x > 1)
jle .L3 // {
leal -1(%ebx), %eax // %eax = x - 1
movl %eax, (%esp) // put (x - 1) on stack
call bar // %eax = bar(x - 1)
addl %ebx, %eax // %eax += x
.L3 // }
addl , %esp // function epilogue
popl %ebx //
popl %ebp //
ret // return %eax
// }
因此 C 看起来与您发布的完全相同:
int bar (int x)
{
if (x > 1)
return bar(x - 1) + x;
return 1;
}
出于历史兴趣:我使用 clang -m32 -S
编译了您的原始(不正确的)C 代码,并在 "optimizing" 之后稍微手动删除了 store/load 对,我得到了类似于您的程序集的东西代码,但很明显你当时错了。从那以后你就修好了。
这是 AT&T 语法
.global bar
.type bar, @function
bar:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl , %esp
movl 8($ebp), %ebx
movl , %eax
cmpl , %ebx
jle .L3
leal -1(%ebx), %eax //subtracts 1 from ebx and stores into eax
movl %eax, (%esp) //putting on stack frame
call bar //recursive call
addl %ebx, %eax // adds %ebx and %eax
.L3 //returns %eax
addl , %esp
popl %ebx
popl %ebp
ret //end of bar
所以我认为这里发生的基本上是检查 %ebx 是否 <= 1,如果是,它 return 是一个。否则,它用 x--;
调用 bar所以我的 C 代码是:
int bar (int x)
{
if (x<= 1)
return 1;
else
return x + bar(x-1);
}
这里的递归调用真的把我骗了。我意识到它用新的 %eax 寄存器调用 bar(基本上变成 x-1)。那么它只是 return 数字的总和吗?
int bar(int x)
{
if (x<= 1)
return 1;
else
return x+bar(x-1);
}
按升序将 x 加到 1
我会这样注释它:
bar: // bar() {
pushl %ebp // function prologue
movl %esp, %ebp //
pushl %ebx //
subl , %esp //
movl 8($ebp), %ebx // %ebx = x
movl , %eax // %eax = 1
cmpl , %ebx // if (x > 1)
jle .L3 // {
leal -1(%ebx), %eax // %eax = x - 1
movl %eax, (%esp) // put (x - 1) on stack
call bar // %eax = bar(x - 1)
addl %ebx, %eax // %eax += x
.L3 // }
addl , %esp // function epilogue
popl %ebx //
popl %ebp //
ret // return %eax
// }
因此 C 看起来与您发布的完全相同:
int bar (int x)
{
if (x > 1)
return bar(x - 1) + x;
return 1;
}
出于历史兴趣:我使用 clang -m32 -S
编译了您的原始(不正确的)C 代码,并在 "optimizing" 之后稍微手动删除了 store/load 对,我得到了类似于您的程序集的东西代码,但很明显你当时错了。从那以后你就修好了。