2016-06-07 2 views
0

어셈블리 함수를 연습용 C 코드에 연결하려고합니다. 다음은 86 어셈블리로 작성 내 조립 기능입니다 : (또는해야한다) 그것은 기본적으로 배열의 최대 값을 찾는 함수를 정의C 코드에서 어셈블리 함수를 호출 할 때 세그먼트 오류가 발생했습니다.

.code32 

.section .text 
.globl max_function 
.type max_function, @function 
# i parametri saranno in ordine inverso a partire da 8(%ebp) 

max_function: 
    pushl %ebp    # save ebp 
    movl %esp, %ebp   # new frame function 
    movl $0, %edi   # first index is 0 
    movl 8(%ebp), %ecx  # ecx is loaded with the number of elements 
    cmpl $0, %ecx   # check that the number of elements is not 0 
    je end_function_err #if it is, exit 

    movl 12(%ebp),%edx  # edx is loaded with the array base 
    movl (%edx), %eax  # first element of the array 

    start_loop: 
    incl %edi    #increment the index 
    cmpl %edi,%ecx   #if it's at the end quit 
    je loop_exit 
    movl (%edx,%edi,4),%ebx #pick the value 
    cmpl %ebx,%eax    #compare with actual maximum value 
    jle start_loop    #less equal -> repeat loop 
    movl %ebx,%eax    #greater -> update value 
    jmp start_loop    #repeat loop 

    loop_exit: 
    jmp end_function   #finish 

end_function:     #exit operations 
    movl %ebp, %esp 
    popl %ebp 
    ret 

end_function_err: 
    movl $0xffffffff, %eax   #return -1 and quit 
    jmp end_function 

그리고 내 C 코드 :

#include <stdio.h> 
#include <stdlib.h> 

extern int max_function(int size, int* values); 

int main(){ 
    int values[] = { 4 , 5 , 7 , 3 , 2 , 8 , 5 , 6 } ; 
    printf("\nMax value is: %d\n",max_function(8,values)); 
} 

gcc -o max max.s max.c으로 컴파일합니다.
코드를 실행할 때 SegmentationFault이 표시됩니다.
용의자는 올바른 방법으로 값에 액세스하지 못하지만 명령 줄에서 호출 할 때 argcargv 값을 인쇄하는 예제 코드에 기반하여 코드를 작성했기 때문에 이유를 알 수 없습니다.

내가

+1

당신은 callee-save 레지스터'% edi'와'% ebx'에서 값을 깨고 있습니다, 그래서 그것은 약간의 문제를 일으킬 것 같아요. – MikeCAT

+0

디버거를 사용하여이 segfault에 대한 자세한 정보를 얻었습니까? – blatinox

+0

아니요. 솔직히 나는 그것을하는 법을 모른다. 교수님은 수업 중에 lldb를 한 번 사용하셨습니다. 내 지식은 지금 거기에서 멈 춥니 다. – magicleon

답변

1

문제점이 있었다 64 비트 데비안 8을 실행 해요 :

  • %ebx 32 비트 용으로 컴파일하지
  • %edi을 보존하지
  • (GCC에 대한 -m32 플래그를 사용했다)
  • cmpl 피연산자가 반전되었습니다.

모두에게 감사드립니다. 문제가 해결되었습니다. 디버깅 도구에 더 초점을 맞출 것입니다 (단계별 분해 및 실행은 매우 유용했습니다)!

+0

어셈블리 파일에서'.code32' 지시어를 제거 할 수 있습니다. 그것 없이는'-m32'를 사용하지 않았기 때문에 아마도 어셈블러 오류가 발생했을 것입니다. –

+0

나는 이미 해냈다;) – magicleon

관련 문제