2011-11-14 4 views
0

세그먼트 화 오류를 반환하는 asm (x86/GAS) 프로그램에 대한 질문이 있습니다. 그것은 피보나치에 관하여 : 나는 algorith 확인이라고 생각 : (의사 코드)asm 프로그램에서 재귀

fibo(int number){ 
    if (n < 2) 
     return number; 
    return fib(n - 1) + fib(n - 2); 

오류가 왜 이해가 안 돼요. C 프로그램이 asm 함수를 호출합니다.

fibo: 
    movl 4(%esp), %ebx #argument n in %ebx 
    cmpl $2, %ebx   # test: is n < 2 ? 
    jnl  recur   # no, recursion 

    jmp  quit    # yes : quit 

recur: 


    movl %ebx, %eax # get value of argument n 
    subl $1, %eax  # n-1 
    pushl %eax  # push n-1 
    call fibo  # recursive call : fib(n-1) 
    movl %eax, %edx # save result in %edx 
    movl %ebx, %eax # get value of argument n 
    subl $2, %eax  # n-2 
    pushl %eax  # push n-2 
    call fibo  # recursive call : fib(-2) 
    addl %edx, %eax # add fib(n-1) + fib(n-2) 

당신이 세그멘트 폴트가 어디 나를 찾는 데 도움이 될 수 있습니다 : 여기

코드인가?

감사합니다.

PS :

quit: movl %ecx, %eax #result in %ecx 
     ret 
+1

잠시만 기다려주십시오.이 코드를 작성했지만 디버거에서 단계를 밟아 문제를 찾을 수 없습니까? –

+2

함수에 대한 스택 프레임을 올바르게 설정하지 않은 것 같습니다. - 어디에서나 'ebp'가 조정되지 않는 것을 볼 수 있습니다 ... –

+0

지옥, 그 원인은 무엇입니까? 그 특별한 재귀 구현은 스택에서 매우 어려울 것입니다. –

답변

3
  1. 어떻게 함수에서 반환에 : 여기가 RET입니까?
  2. call에 레지스터의 값을 보존 하시겠습니까?

답변을 통해 해결책을 얻으실 수 있습니다.

1

다른 사람들이 지적했듯이, 중요한 명령 인 배우기 지시는 보여주지 않습니다. 또한 edx에서 add의 중간 결과를 저장합니다. 그것은 작동하지 않을 것입니다 - 다음에 오는 재귀 호출은 또한이를 수행 할 것이고이 호출 레벨에서 얻은 가치를 깨뜨릴 것입니다. 스택에 중간 값을 저장해야합니다.

+0

중간 값을 저장했지만 왜 % ebp를 사용해야하는지 이해하지 못한다. 이미 % esp : 스택을 복제합니까? thanks – lilawood

+1

ebp를 사용하여 명시 적 스택 프레임을 설정할 필요가 없습니다. 개발자는 esp를 사용할 수 있습니다. 개발 중에 오류가 발생하기 쉽습니다. 그게 전부입니다. –

+0

답장을 보내 주셔서 감사합니다. – lilawood