>
int suma(int* array, int len)
{
    asm("    xor %eax, %eax           # resultado = 0   \n"
        "    xor %edx, %edx           # i = 0           \n"
        "1:  add (%rdi,%rdx,4), %eax  # res += array[i] \n"
        "    inc %edx                 # ++i             \n"
        "    cmp %edx,%esi            # i < len?        \n"
        "    jne 1b                   # repetir         \n"
//      "    ret                                        \n"
       );
}
int main()
{
    int v[100];
    return suma(v, 100);
}

gcc가 왜 ret 를 삽입 하는가   suma() 의 끝에서   -O0 에서 하지만 -O3 에 직접 추가해야합니다. ?

gcc -v 에서 :

gcc version 8.2.1 20181011 (Red Hat 8.2.1-4) (GCC)


  • 답변 # 1

    와이즈 비즈

    I assume 64bit..., array in rdi, len in esi.

    가 아닌인라인asm을 사용하고 있습니다.  컴파일러는 원하는 컨텍스트에서 인라인 asm 템플릿 블록을 사용할 수 있습니다. 입력/출력 제약 조건을 사용하지 못하고 컴파일러에 알리지 않고 레지스터를 클로버하므로 최적화를 비활성화하지 않으면 완전히 중단됩니다.

    주된 질문에 대답하기 위해 컴파일러는 단순히 __attribute__((naked,noinline)) 를 인라인합니다.   suma 로 . 암시 적으로 main 입니다  (기본 asm 문이므로) 최적화되지 않습니다.

    그러나 비 공여 기능 ( volatile )의 끝에서 실행 ), 정의되지 않은 동작이므로 현대 GCC는 suma 를 포기하고 생략합니다.  교수. 실행은 정의되지 않은 동작으로 인해 해당 경로를 사용할 수 없으며 코드 생성을 방해하지 않는다고 가정합니다.

    ret 를 추가하면   return 0; 의 끝까지 그런 다음 suma   main 로 끝날 것입니다  지시.

    놀랍게도 gcc는 -O3 -Wall을 사용하여 Godbolt 컴파일러 탐색기에 경고를 하나만 표시합니다.

    ret
    
    

    <source>: In function 'int suma(int*, int)': <source>:13:1: warning: no return statement in function returning non-void [-Wreturn-type] } ^ 에 대한 결과 asm 출력  이것은 RDI가 main 이기 때문에 물론 완전히 고장났습니다. ;그것은 argc 를위한 공간을 예약하지 않았습니다  C 소스에서 사용되지 않거나 무언가를했기 때문입니다.

    int v[100]
    
    
    main: xor %eax, %eax # resultado = 0 xor %edx, %edx # i = 0 1: add (%rdi,%rdx,4), %eax # res += array[i] inc %edx # ++i cmp %edx,%esi # i < len? jne 1b # repetir 와 함께   return 0; 의 끝에서 , 그것과 suma 의 주요 끝  ;와이즈 비즈 물론 xorl %eax, %eax  인라인 asm이 입력 제약 조건을 사용하지 않기 때문에 여전히 완전히 손상되었습니다.

    ret

  • 이전 MySQL 데이터베이스에 위도/경도를 저장할 때 사용하기에 이상적인 데이터 유형은 무엇입니까?
  • 다음 javascript - instagram - 외부 사이트에서 사진 좋아하기