[英]Going from Assembly to C code
這是AT&T語法
.global bar
.type bar, @function
bar:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
movl 8($ebp), %ebx
movl $1, %eax
cmpl $1, %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 $20, %esp
popl %ebx
popl %ebp
ret //end of bar
所以我認為這里發生的基本上是檢查%ebx是否<= 1,如果是,則返回一個。 否則,它用x--調用bar;
所以我的C代碼是:
int bar (int x)
{
if (x<= 1)
return 1;
else
return x + bar(x-1);
}
遞歸調用實際上是在欺騙我。 我意識到它使用新的%eax寄存器(基本上變成x-1)調用bar。 那么它只返回數字的總和嗎?
我這樣注釋:
bar: // bar() {
pushl %ebp // function prologue
movl %esp, %ebp //
pushl %ebx //
subl $20, %esp //
movl 8($ebp), %ebx // %ebx = x
movl $1, %eax // %eax = 1
cmpl $1, %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 $20, %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代碼,並在手動“優化”之后消除了存儲/加載對,我得到了類似於匯編代碼的東西,但很明顯你有那一刻錯了。 你從那時起就修好了。
int bar(int x)
{
if (x<= 1)
return 1;
else
return x+bar(x-1);
}
按升序將x加1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.