반응형
GCC가 결과를 사용하지 않고 libc의 sqrt ()를 호출하는 이유는 무엇입니까?
GCC 6.3, 다음 C ++ 코드 사용 :
#include <cmath>
#include <iostream>
void norm(double r, double i)
{
double n = std::sqrt(r * r + i * i);
std::cout << "norm = " << n;
}
다음 x86-64 어셈블리를 생성합니다.
norm(double, double):
mulsd %xmm1, %xmm1
subq $24, %rsp
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
pxor %xmm1, %xmm1
ucomisd %xmm0, %xmm1
sqrtsd %xmm0, %xmm2
movsd %xmm2, 8(%rsp)
jbe .L2
call sqrt
.L2:
movl std::cout, %edi
movl $7, %edx
movl $.LC1, %esi
call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
movsd 8(%rsp), %xmm0
movl std::cout, %edi
addq $24, %rsp
jmp std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
에 대한 호출의 std::sqrt
경우 GCC는 먼저 사용 sqrtsd
하여 결과를 스택에 저장합니다. 오버플로되면 libc sqrt
함수 를 호출합니다 . 그러나 그 xmm0
이후와에 대한 두 번째 호출 전에는 절대 저장하지 않고 operator<<
스택에서 값을 복원합니다 (를 xmm0
처음 호출 할 때 손실 되었기 때문 operator<<
).
더 간단한을 사용하면 std::cout << n;
훨씬 더 분명합니다.
subq $24, %rsp
movsd %xmm1, 8(%rsp)
call sqrt
movsd 8(%rsp), %xmm1
movl std::cout, %edi
addq $24, %rsp
movapd %xmm1, %xmm0
jmp std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)
GCC xmm0
가 libc에서 계산 한 값을 사용하지 않는 이유는 무엇 sqrt
입니까?
sqrt
결과를 계산하기 위해 호출 할 필요가 없습니다 . 이미 SQRTSD 명령에 의해 계산되었습니다. sqrt
음수가 전달 될 때 표준에 따라 필요한 동작을 생성하도록 호출 합니다 sqrt
(예 errno
: 부동 소수점 예외 설정 및 / 또는 발생). PXOR, UCOMISD 및 JBE 명령어는 인수가 0보다 작은 지 여부를 테스트하고 sqrt
이것이 사실이 아닌 경우 호출을 건너 뜁니다 .
참조 URL : https://stackoverflow.com/questions/43303090/why-does-gcc-call-libcs-sqrt-without-using-its-result
반응형
'IT박스' 카테고리의 다른 글
Project.json 정의 dnx451 대 .dotnet (4.51) (0) | 2020.12.31 |
---|---|
파이썬 애플리케이션을 정적 바이너리로 컴파일하는 방법이 있습니까? (0) | 2020.12.31 |
MongoDB와 CouchDB는 완벽한 대체품입니까? (0) | 2020.12.31 |
비밀번호 안전성 검사 라이브러리 (0) | 2020.12.31 |
하나 이상의 단어로 gem의 이름을 지정할 때 대시 나 밑줄을 사용해야합니까? (0) | 2020.12.31 |