Windows Mobile 6 ARMV4I 용 Visual Studio 2008 C++을 사용하고 있으며 VS에서 생성 된 ARM 어셈블리 코드를 읽고 응용 프로그램 내에서 비정상적인 버퍼 복사본을 최소화하는 방법을 배우려고합니다. 그래서, 나는이처럼 보이는 테스트 응용 프로그램을 만든 다음 Foo
생성자 또는 컴파일러가 최적화 할 수있는 경우 주어 졌을 때 Create
에 의해 반환 된 버퍼가 복사되는 경우 이해하고 싶습니다 어셈블리 코드에서 불필요한 버퍼 복사본 찾기
#include <vector>
typedef std::vector<BYTE> Buf;
class Foo
{
public:
Foo(Buf b) { b_.swap(b); };
private:
Buf b_;
};
Buf Create()
{
Buf b(1024);
b[ 0 ] = 0x0001;
return b;
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo f(Create());
return 0;
}
멀리 복사하십시오.
class Foo
{
public:
Foo(Buf b) { b_.swap(b); };
0001112C stmdb sp!, {r4 - r7, lr}
00011130 mov r7, r0
00011134 mov r3, #0
00011138 str r3, this
0001113C str r3, [r7, #4]
00011140 str r3, [r7, #8]
00011144 ldr r3, this
00011148 ldr r2, this
0001114C mov r5, r7
00011150 mov r4, r1
00011154 str r3, this, #4
00011158 str r2, this, #4
0001115C mov r6, r1
00011160 ldr r2, this
00011164 ldr r3, this
00011168 mov lr, r7
0001116C str r3, this
00011170 str r2, this
00011174 ldr r2, [lr, #8]!
00011178 ldr r3, [r6, #8]!
0001117C str r3, this
00011180 str r2, this
00011184 ldr r3, this
00011188 movs r0, r3
0001118C beq |Foo::Foo + 0x84 (111b0h)|
00011190 ldr r3, [r1, #8]
00011194 sub r1, r3, r0
00011198 cmp r1, #0x80
0001119C bls |Foo::Foo + 0x80 (111ach)|
000111A0 bl 000112D4
000111A4 mov r0, r7
000111A8 ldmia sp!, {r4 - r7, pc}
000111AC bl |stlp_std::__node_alloc::_M_deallocate (11d2ch)|
000111B0 mov r0, r7
000111B4 ldmia sp!, {r4 - r7, pc}
--- ...\stlport\stl\_vector.h -----------------------------
// snip!
--- ...\asm_test.cpp
private:
Buf b_;
};
Buf Create()
{
00011240 stmdb sp!, {r4, lr}
00011244 mov r4, r0
Buf b(1024);
00011248 mov r1, #1, 22
0001124C bl |
b[ 0 ] = 0x0001;
00011250 ldr r3, [r4]
00011254 mov r2, #1
return b;
}
int _tmain(int argc, _TCHAR* argv[])
{
00011264 str lr, [sp, #-4]!
00011268 sub sp, sp, #0x18
Foo f(Create());
0001126C add r0, sp, #0xC
00011270 bl |Create (11240h)|
00011274 mov r1, r0
00011278 add r0, sp, #0
0001127C bl |Foo::Foo (1112ch)|
return 0;
00011280 ldr r0, argc
00011284 cmp r0, #0
00011288 beq |wmain + 0x44 (112a8h)|
0001128C ldr r3, [sp, #8]
00011290 sub r1, r3, r0
00011294 cmp r1, #0x80
00011298 bls |wmain + 0x40 (112a4h)|
0001129C bl 000112D4
000112A0 b |wmain + 0x44 (112a8h)|
000112A4 bl |stlp_std::__node_alloc::_M_deallocate (11d2ch)|
000112A8 mov r0, #0
}
나는 Buf
구조가 복사되는 위치를 이해하는 어셈블리 코드에서 어떤 패턴을 볼 수 : 최적화가 켜져와 릴리스에서이 같은 어셈블리를 생성, 구축
C++ 코드에서보기가 쉽지 않습니까? 모든 사본을 예측할 수 있습니다. –
C++ 코드를 살펴보면'Buf'가'Foo' 생성자와'Create' 함수에서 반환 될 때 두 곳에서 복사된다는 것을 알 수 있습니다. –
@Etienne de Martel - create 함수가 반환 한'Buf'는 RVO에 의해 최적화되어야합니다. 컴파일러는'Foo' 생성자에서도 복사본을 최적화 할 수 있습니다. 나는 모른다. 최적화를 적용 할 수있는 어셈블리를 어떻게 읽을 수 있는지 이해하려고합니다. – PaulH