Reversing
[C] Streaming SIMD Extensions(SSE) API
Tribal
2018. 8. 1. 11:12
Intel 기반의 프로그램을 분석하다 보면 부동 소수점 연산이나 최적화를 하기 위해서 xmm 레지스터를 사용하는 것을 볼 수 있다. 이 때 instruction도 레지스터를 지원하기 위해서 변하게 된다. IDA로 리버싱을 하면 이러한 instruction을 '_mm'으로 시작하는 api로 보여주는데 단순히 어떤 연산을 하는지는 이해할 수 있지만, 실제로 어떻게 레지스터가 사용되는지는 조금 이해가 어렵다고 생각한다.
SSE 관련 헤더 : emmintrin.h
SSE 관련 API(참고 : https://software.intel.com/sites/landingpage/IntrinsicsGuide/)
- _mm_cvtsi32_si128 : https://msdn.microsoft.com/zh-cn/library/ct3539ha(v=vs.110).aspx
- _mm_shuffle_epi32 : https://msdn.microsoft.com/zh-cn/library/56f67xbk%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
- ...
예제 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <emmintrin.h> int main(void) { // v0 = 13 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 __m128i v0 = _mm_cvtsi32_si128(0x213); // V1 = 13 02 13 02 00 00 00 00 00 00 00 00 00 00 00 00 __m128i v1 = _mm_unpacklo_epi16(v0, v0); // V2 = 26 04 26 04 00 00 00 00 00 00 00 00 00 00 00 00 __m128i v2 = _mm_adds_epi16(v1, v1); // V3 = 13 02 13 02 13 02 13 02 13 02 13 02 13 02 13 02 __m128i v3 = _mm_shuffle_epi32(_mm_unpacklo_epi16(v1, v1), 0); return 0; } | cs |
Visual Studio에서 위의 예제를 컴파일에서 디버깅해보면 메모리의 값이 주석과 같이 결과가 변화하는 것을 볼 수 있다. 궁금한 결과가 있다면 위의 예제처럼 직접 컴파일해서 결과를 확인해 보는게 좋은 것 같다.
참고
- 위키 : https://ko.wikipedia.org/wiki/스트리밍_SIMD_확장
- Intel Guide : https://software.intel.com/sites/landingpage/IntrinsicsGuide/