Caesar cipher oop



  • for (size_t j = 0; i < length; buffer[j] = rot13 (buffer[j]), ++j);
    

    Wenn du so einen crap baust, brauchste nicht zu heulen, das nichts läuft.

    Der Code von mir funktioniert und das einwandfrei. Aber bitte. Laber du mal ruhig, wir haben hier gerade eine ganz andere Thematik.


  • Administrator

    @Simon2,
    Ich habe noch überlegt, ob ich das "muss" abschwächen sollte. Aber dachte: "Ach dagegen wird sicher niemand einen Einwand haben."
    War wohl falsch gedacht 🙂
    Aber recht hast du natürlich schon 😉

    unsigned long schrieb:

    Was mir jedoch Kopfzerbrechen bereitet ist hierfür die STL zu benutzen. Keine Frage, STL ist ein feines Teil, aber gerade für sowas denke ich, ist es eher als ob man eine Neutronenbombe auf eine Ameise wirft. Ich denke nicht, das hier die Anwendung der STL irgendeinen Vorteil birgt, eher Abzüge in Performance, Overhead usw. mit sich führt.

    Die STL-Algorithmen werden meistens völlig wegoptimiert. Daher ist dein Bedenken hier grundlos. Ein std::transform ist intern auch nichts anderes als eine Schleife. Was man schlussendlich wirklich gewinnt ist Übersicht. Ein std::transform lässt sich deutlich besser lesen als eine for -Schleife.

    Was womöglich gewisse Performanceeinbussen bringen könnte, ist die Verwendung des std::string als Puffer. Hier werden sehr wahrscheinlich beim Iterieren zusätzliche Bereichsprüfungen durchgeführt. Aber man kann den std::string natürlich ohne Probleme auch wieder durch deinen char Puffer ersetzen. Die Verwendung von std::transform kann immer noch genutzt werden. Ich könnte mir vorstellen, dass man dann sogar einen Performancegewinn erzielen könnte, da man gleich mit Zeigerarithmetik arbeitet. Allerdings ist das nur eine Spekulation von meiner Seite 😉
    Ich habe einen std::string genutzt, weil ich den Hintergedanken hatte, dass man mit dem String womöglich mehr machen möchte, als nur kodieren und dekodieren. Wahrscheinlich möchte man zuerst etwas vom Benutzer einlesen lassen oder ähnliches und da erleichtert einem die Verwendung des std::string einiges.

    Gespräche über die Performance sollte man eigentlich sowieso besser zusammen mit einem Profiler machen. Sonst kann man eigentlich immer nur spekulieren. Allerdings wurde schon mehrmals bewiesen, dass STL Algorithmen nicht langsamer sind als normale eigene Schleifen, bzw. kein Nachteil durch diese entsteht.
    Zudem ist Performance ja schön und gut, aber die Übersicht sollte man bei einem Programm auch im Hinterkopf behalten. Optimieren kann man im nachhinein immer noch. Auch sollte man die Programmiersprache, welche man gewählt halt, auch benutzen. Wenn etwas besser in C geschrieben werden sollte, dann kann man natürlich die Programmiersprache wechseln. Aber ein zwanghaftes mischen von C und C++, vor allem an Stellen, wo man gar nicht so recht weiss, ob man etwas durch die Verwendung von C gewinnt, halte ich für ein schlechtes Vorgehen. Sowas führt zu unübersichtlichem und dadurch unwartbarem Code.

    Grüssli



  • Dravere schrieb:

    @Simon2,
    Ich habe noch überlegt, ob ich das "muss" abschwächen sollte. Aber dachte: "Ach dagegen wird sicher niemand einen Einwand haben."
    War wohl falsch gedacht 🙂
    Aber recht hast du natürlich schon 😉
    ...

    Tja ... wie sagte meine Deutschlehrerin immer: "Pauschalisierungen sind immer falsch!" 😉
    Und schön finde ich das schon mit dem transform() ...

    Gruß,

    Simon2.



  • Hi,

    also ich war einfach mal so frei, die beiden Sources durch den aktuellen VC++2008 SP1 Compiler zu jagen (Standard Release, normale Optimierungen auf Speed, Multi-Threaded DLL) und mal den Assembler-Output anzuzeigen. Ich denke mal, dass dieser Bände ´für sich spricht, wenn man als Faustregel folgende nimmt: "Jede Anweisung kostet Zeit."

    Variante 1:

    #include <stdio.h>
    #include <string.h>
    
    inline char rot13 (char c)
    { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); }
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        size_t length = strlen (buffer);
    
        // orginal
        printf ("orginal: %s\n", buffer);
    
        // encodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("encoded: %s\n", buffer);
    
        // decodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("decoded: %s\n", buffer);
    }
    

    Assembler-Output:

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 
    
    	TITLE	x:\main.cpp
    	.686P
    	.XMM
    	include listing.inc
    	.model	flat
    
    INCLUDELIB OLDNAMES
    
    PUBLIC	?rot13@@YADD@Z					; rot13
    PUBLIC	??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@ ; `string'
    PUBLIC	??_C@_0N@NOAGLDLO@orginal?3?5?$CFs?6?$AA@	; `string'
    PUBLIC	??_C@_0N@HCAHLMCD@encoded?3?5?$CFs?6?$AA@	; `string'
    PUBLIC	??_C@_0N@NOADMBKI@decoded?3?5?$CFs?6?$AA@	; `string'
    EXTRN	@__security_check_cookie@4:PROC
    EXTRN	__imp__printf:PROC
    ;	COMDAT ??_C@_0N@NOADMBKI@decoded?3?5?$CFs?6?$AA@
    CONST	SEGMENT
    ??_C@_0N@NOADMBKI@decoded?3?5?$CFs?6?$AA@ DB 'decoded: %s', 0aH, 00H ; `string'
    CONST	ENDS
    ;	COMDAT ??_C@_0N@HCAHLMCD@encoded?3?5?$CFs?6?$AA@
    CONST	SEGMENT
    ??_C@_0N@HCAHLMCD@encoded?3?5?$CFs?6?$AA@ DB 'encoded: %s', 0aH, 00H ; `string'
    CONST	ENDS
    ;	COMDAT ??_C@_0N@NOAGLDLO@orginal?3?5?$CFs?6?$AA@
    CONST	SEGMENT
    ??_C@_0N@NOAGLDLO@orginal?3?5?$CFs?6?$AA@ DB 'orginal: %s', 0aH, 00H ; `string'
    CONST	ENDS
    ;	COMDAT ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@
    CONST	SEGMENT
    ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@ DB 'hallo, caeser rock'
    	DB	's!', 00H					; `string'
    ; Function compile flags: /Ogtpy
    ; File x:\main.cpp
    CONST	ENDS
    ;	COMDAT ?rot13@@YADD@Z
    _TEXT	SEGMENT
    ?rot13@@YADD@Z PROC					; rot13, COMDAT
    ; _c$ = eax
    
    ; 5    : { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); }
    
    	not	al
    	push	esi
    	movsx	esi, al
    	mov	ecx, esi
    	or	ecx, 32					; 00000020H
    	not	ecx
    	mov	eax, 1321528399				; 4ec4ec4fH
    	imul	ecx
    	sar	edx, 2
    	mov	eax, edx
    	shr	eax, 31					; 0000001fH
    	add	eax, edx
    	lea	ecx, DWORD PTR [eax+eax-11]
    	mov	eax, 1
    	cdq
    	idiv	ecx
    	mov	edx, eax
    	imul	edx, 13					; 0000000dH
    	mov	eax, esi
    	not	eax
    	sub	eax, edx
    	pop	esi
    	ret	0
    ?rot13@@YADD@Z ENDP					; rot13
    _TEXT	ENDS
    PUBLIC	__$ArrayPad$
    PUBLIC	_main
    EXTRN	___security_cookie:DWORD
    ; Function compile flags: /Ogtpy
    ;	COMDAT _main
    _TEXT	SEGMENT
    _buffer$ = -28						; size = 21
    __$ArrayPad$ = -4					; size = 4
    _main	PROC						; COMDAT
    
    ; 8    : {
    
    	sub	esp, 28					; 0000001cH
    	mov	eax, DWORD PTR ___security_cookie
    	xor	eax, esp
    	mov	DWORD PTR __$ArrayPad$[esp+28], eax
    
    ; 9    :     char buffer[] = "hallo, caeser rocks!";
    
    	mov	ecx, DWORD PTR ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@+4
    	mov	eax, DWORD PTR ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@
    	mov	edx, DWORD PTR ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@+8
    	push	ebx
    	push	ebp
    	push	esi
    	mov	DWORD PTR _buffer$[esp+44], ecx
    	mov	ecx, DWORD PTR ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@+16
    	push	edi
    	mov	DWORD PTR _buffer$[esp+44], eax
    	mov	eax, DWORD PTR ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@+12
    	mov	DWORD PTR _buffer$[esp+52], edx
    	mov	dl, BYTE PTR ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@+20
    
    ; 10   :     size_t length = strlen (buffer);
    
    	lea	edi, DWORD PTR _buffer$[esp+44]
    	mov	DWORD PTR _buffer$[esp+60], ecx
    	mov	DWORD PTR _buffer$[esp+56], eax
    	mov	BYTE PTR _buffer$[esp+64], dl
    	lea	ecx, DWORD PTR [edi+1]
    $LL17@main:
    	mov	al, BYTE PTR [edi]
    	inc	edi
    	test	al, al
    	jne	SHORT $LL17@main
    
    ; 11   : 
    ; 12   :     // orginal
    ; 13   :     printf ("orginal: %s\n", buffer);
    
    	mov	ebp, DWORD PTR __imp__printf
    	lea	eax, DWORD PTR _buffer$[esp+44]
    	push	eax
    	push	OFFSET ??_C@_0N@NOAGLDLO@orginal?3?5?$CFs?6?$AA@
    	sub	edi, ecx
    	call	ebp
    	add	esp, 8
    
    ; 14   : 
    ; 15   :     // encodieren
    ; 16   :     for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
    
    	xor	esi, esi
    	test	edi, edi
    	jbe	SHORT $LN4@main
    $LL18@main:
    	mov	cl, BYTE PTR _buffer$[esp+esi+44]
    	not	cl
    	movsx	edx, cl
    	or	edx, 32					; 00000020H
    	not	edx
    	mov	eax, 1321528399				; 4ec4ec4fH
    	imul	edx
    	sar	edx, 2
    	mov	eax, edx
    	shr	eax, 31					; 0000001fH
    	add	eax, edx
    	lea	ebx, DWORD PTR [eax+eax-11]
    	mov	eax, 1
    	cdq
    	idiv	ebx
    	mov	dl, 13					; 0000000dH
    	not	cl
    	inc	esi
    	imul	dl
    	sub	cl, al
    	mov	BYTE PTR _buffer$[esp+esi+43], cl
    	cmp	esi, edi
    	jb	SHORT $LL18@main
    $LN4@main:
    
    ; 17   :     printf ("encoded: %s\n", buffer);
    
    	lea	eax, DWORD PTR _buffer$[esp+44]
    	push	eax
    	push	OFFSET ??_C@_0N@HCAHLMCD@encoded?3?5?$CFs?6?$AA@
    	call	ebp
    	add	esp, 8
    
    ; 18   : 
    ; 19   :     // decodieren
    ; 20   :     for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
    
    	xor	esi, esi
    	test	edi, edi
    	jbe	SHORT $LN1@main
    	npad	8
    $LL19@main:
    	mov	cl, BYTE PTR _buffer$[esp+esi+44]
    	not	cl
    	movsx	edx, cl
    	or	edx, 32					; 00000020H
    	not	edx
    	mov	eax, 1321528399				; 4ec4ec4fH
    	imul	edx
    	sar	edx, 2
    	mov	eax, edx
    	shr	eax, 31					; 0000001fH
    	add	eax, edx
    	lea	ebx, DWORD PTR [eax+eax-11]
    	mov	eax, 1
    	cdq
    	idiv	ebx
    	mov	dl, 13					; 0000000dH
    	not	cl
    	inc	esi
    	imul	dl
    	sub	cl, al
    	mov	BYTE PTR _buffer$[esp+esi+43], cl
    	cmp	esi, edi
    	jb	SHORT $LL19@main
    $LN1@main:
    
    ; 21   :     printf ("decoded: %s\n", buffer);
    
    	lea	eax, DWORD PTR _buffer$[esp+44]
    	push	eax
    	push	OFFSET ??_C@_0N@NOADMBKI@decoded?3?5?$CFs?6?$AA@
    	call	ebp
    
    ; 22   : }
    
    	mov	ecx, DWORD PTR __$ArrayPad$[esp+52]
    	add	esp, 8
    	pop	edi
    	pop	esi
    	pop	ebp
    	pop	ebx
    	xor	ecx, esp
    	xor	eax, eax
    	call	@__security_check_cookie@4
    	add	esp, 28					; 0000001cH
    	ret	0
    _main	ENDP
    _TEXT	ENDS
    END
    

    Variante 2:

    #include <string>
    #include <iostream>
    #include <algorithm>
    
    char rot13(char c)
    {
        return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13);
    }
    
    int main()
    {
        std::string buffer = "hallo, caeser rocks!";
    
        // originial
        std::cout << "Original: " << buffer << std::endl;
    
        // encoding
        std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13);
        std::cout << "Encoded:  " << buffer << std::endl;
    
        // decoding
        std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13);
        std::cout << "Decoded:  " << buffer << std::endl;
    
        return 0;
    }
    

    Assembler-Output:

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 
    
    	TITLE	x:\main.cpp
    	.686P
    	.XMM
    	include listing.inc
    	.model	flat
    
    INCLUDELIB OLDNAMES
    
    PUBLIC	??_C@_0P@GHFPNOJB@bad?5allocation?$AA@		; `string'
    PUBLIC	??0_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base
    PUBLIC	??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z ; std::basic_ostream<char,std::char_traits<char> >::sentry::sentry
    PUBLIC	??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::~_Sentry_base
    PUBLIC	??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ; std::basic_ostream<char,std::char_traits<char> >::sentry::~sentry
    PUBLIC	??Bsentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QBE_NXZ ; std::basic_ostream<char,std::char_traits<char> >::sentry::operator bool
    PUBLIC	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    PUBLIC	??$_Iter_random@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@std@@YA?AUrandom_access_iterator_tag@0@ABV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z ; std::_Iter_random<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> > >
    PUBLIC	?_Has_container@_Iterator_base_secure@std@@QBE_NXZ ; std::_Iterator_base_secure::_Has_container
    PUBLIC	??Y?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z ; std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=
    PUBLIC	??Y?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=
    PUBLIC	??H?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV01@H@Z ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+
    PUBLIC	?_Checked_iterator_base@?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPADXZ ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::_Checked_iterator_base
    PUBLIC	??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U_Different_checked_iterator_base_type_tag@2@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@U_Different_checked_iterator_base_type_tag@0@@Z ; std::_Checked_base<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_Different_checked_iterator_base_type_tag>
    PUBLIC	??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z ; std::_Checked_base<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> > >
    PUBLIC	??$_Transform@PADPADP6ADD@ZUforward_iterator_tag@std@@@std@@YAPADPAD00P6ADD@ZUforward_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ; std::_Transform<char *,char *,char (__cdecl*)(char),std::forward_iterator_tag>
    PUBLIC	??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ; std::_Transform<char *,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    PUBLIC	??$transform@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@V10@00P6ADD@Z@Z ; std::transform<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    PUBLIC	??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@ ; `string'
    PUBLIC	??_C@_0L@EMJAFNHM@Original?3?5?$AA@		; `string'
    PUBLIC	??_C@_0L@OJEBJNBO@Encoded?3?5?5?$AA@		; `string'
    PUBLIC	??_C@_0L@NACPLJCJ@Decoded?3?5?5?$AA@		; `string'
    EXTRN	@__security_check_cookie@4:PROC
    EXTRN	__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z:PROC
    EXTRN	__imp_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ:PROC
    EXTRN	__imp_?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ:PROC
    EXTRN	__imp_?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ:PROC
    EXTRN	__imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z:PROC
    EXTRN	__imp_?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z:PROC
    EXTRN	__imp_??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z:PROC
    EXTRN	__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A:BYTE
    EXTRN	__imp_?length@?$char_traits@D@std@@SAIPBD@Z:PROC
    EXTRN	__imp_?eq_int_type@?$char_traits@D@std@@SA_NABH0@Z:PROC
    EXTRN	__imp_?eof@?$char_traits@D@std@@SAHXZ:PROC
    EXTRN	__imp_?flags@ios_base@std@@QBEHXZ:PROC
    EXTRN	__imp_?width@ios_base@std@@QBEHXZ:PROC
    EXTRN	__imp_?width@ios_base@std@@QAEHH@Z:PROC
    EXTRN	__imp_?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z:PROC
    EXTRN	__imp_?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHPBDH@Z:PROC
    EXTRN	__imp_?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z:PROC
    EXTRN	__imp_?fill@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEDXZ:PROC
    EXTRN	__imp_?rdstate@ios_base@std@@QBEHXZ:PROC
    EXTRN	__imp_?good@ios_base@std@@QBE_NXZ:PROC
    EXTRN	__imp_?tie@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_ostream@DU?$char_traits@D@std@@@2@XZ:PROC
    EXTRN	__imp_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ:PROC
    EXTRN	__imp_?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ:PROC
    EXTRN	__imp_?uncaught_exception@std@@YA_NXZ:PROC
    EXTRN	__imp_?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ:PROC
    EXTRN	__imp_?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ:PROC
    EXTRN	__imp_?rdbuf@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_streambuf@DU?$char_traits@D@std@@@2@XZ:PROC
    EXTRN	__imp___invalid_parameter_noinfo:PROC
    EXTRN	__imp_?_Myptr@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IAEPADXZ:PROC
    ;	COMDAT ??_C@_0L@NACPLJCJ@Decoded?3?5?5?$AA@
    CONST	SEGMENT
    ??_C@_0L@NACPLJCJ@Decoded?3?5?5?$AA@ DB 'Decoded:  ', 00H ; `string'
    CONST	ENDS
    ;	COMDAT ??_C@_0L@OJEBJNBO@Encoded?3?5?5?$AA@
    CONST	SEGMENT
    ??_C@_0L@OJEBJNBO@Encoded?3?5?5?$AA@ DB 'Encoded:  ', 00H ; `string'
    CONST	ENDS
    ;	COMDAT ??_C@_0L@EMJAFNHM@Original?3?5?$AA@
    CONST	SEGMENT
    ??_C@_0L@EMJAFNHM@Original?3?5?$AA@ DB 'Original: ', 00H ; `string'
    CONST	ENDS
    ;	COMDAT ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@
    CONST	SEGMENT
    ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@ DB 'hallo, caeser rock'
    	DB	's!', 00H					; `string'
    __bad_alloc_Message DD FLAT:??_C@_0P@GHFPNOJB@bad?5allocation?$AA@
    ;	COMDAT ??_C@_0P@GHFPNOJB@bad?5allocation?$AA@
    CONST	SEGMENT
    ??_C@_0P@GHFPNOJB@bad?5allocation?$AA@ DB 'bad allocation', 00H ; `string'
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\xstring
    CONST	ENDS
    ;	COMDAT ?_Checked_iterator_base@?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPADXZ
    _TEXT	SEGMENT
    ?_Checked_iterator_base@?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPADXZ PROC ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::_Checked_iterator_base, COMDAT
    ; _this$ = eax
    
    ; 358  : 		return const_cast<pointer>(this->_Myptr);
    
    	mov	eax, DWORD PTR [eax+4]
    
    ; 359  : 	}
    
    	ret	0
    ?_Checked_iterator_base@?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPADXZ ENDP ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::_Checked_iterator_base
    _TEXT	ENDS
    PUBLIC	?rot13@@YADD@Z					; rot13
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\algorithm
    ;	COMDAT ??$_Transform@PADPADP6ADD@ZUforward_iterator_tag@std@@@std@@YAPADPAD00P6ADD@ZUforward_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z
    _TEXT	SEGMENT
    ___formal$ = 8						; size = 1
    ___formal$ = 12						; size = 1
    ??$_Transform@PADPADP6ADD@ZUforward_iterator_tag@std@@@std@@YAPADPAD00P6ADD@ZUforward_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z PROC ; std::_Transform<char *,char *,char (__cdecl*)(char),std::forward_iterator_tag>, COMDAT
    ; __First$ = ecx
    ; __Last$ = ebx
    ; __Dest$ = eax
    
    ; 664  : 	{	// transform [_First, _Last) with _Func
    
    	push	esi
    	mov	esi, ecx
    	push	edi
    	mov	edi, eax
    
    ; 665  : 	_DEBUG_RANGE(_First, _Last);
    ; 666  : 	_DEBUG_POINTER(_Dest);
    ; 667  : 	_DEBUG_POINTER(_Func);
    ; 668  : 	for (; _First != _Last; ++_First, ++_Dest)
    
    	cmp	esi, ebx
    	je	SHORT $LN1@Transform
    	npad	6
    $LL3@Transform:
    
    ; 669  : 		*_Dest = _Func(*_First);
    
    	movzx	eax, BYTE PTR [esi]
    	push	eax
    	call	?rot13@@YADD@Z				; rot13
    	mov	BYTE PTR [edi], al
    	inc	esi
    	add	esp, 4
    	inc	edi
    	cmp	esi, ebx
    	jne	SHORT $LL3@Transform
    
    ; 670  : 	return (_Dest);
    
    	mov	eax, edi
    $LN1@Transform:
    	pop	edi
    	pop	esi
    
    ; 671  : 	}
    
    	ret	0
    ??$_Transform@PADPADP6ADD@ZUforward_iterator_tag@std@@@std@@YAPADPAD00P6ADD@ZUforward_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ENDP ; std::_Transform<char *,char *,char (__cdecl*)(char),std::forward_iterator_tag>
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\xutility
    _TEXT	ENDS
    ;	COMDAT ??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U_Different_checked_iterator_base_type_tag@2@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@U_Different_checked_iterator_base_type_tag@0@@Z
    _TEXT	SEGMENT
    ___formal$ = 8						; size = 1
    ??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U_Different_checked_iterator_base_type_tag@2@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@U_Different_checked_iterator_base_type_tag@0@@Z PROC ; std::_Checked_base<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_Different_checked_iterator_base_type_tag>, COMDAT
    ; __It$ = eax
    
    ; 1139 : 		return _It._Checked_iterator_base();
    
    	mov	eax, DWORD PTR [eax+4]
    
    ; 1140 : 	}
    
    	ret	0
    ??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U_Different_checked_iterator_base_type_tag@2@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@U_Different_checked_iterator_base_type_tag@0@@Z ENDP ; std::_Checked_base<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_Different_checked_iterator_base_type_tag>
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??$_Iter_random@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@std@@YA?AUrandom_access_iterator_tag@0@ABV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z
    _TEXT	SEGMENT
    ??$_Iter_random@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@std@@YA?AUrandom_access_iterator_tag@0@ABV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z PROC ; std::_Iter_random<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> > >, COMDAT
    ; ___$ReturnUdt$ = eax
    
    ; 994  : 	typename _Iter_random_helper<
    ; 995  : 		iterator_traits<_Iter1>::iterator_category, 
    ; 996  : 		iterator_traits<_Iter2>::iterator_category>::_Iter_random_cat _Cat;
    ; 997  : 	return (_Cat);
    ; 998  : 	}
    
    	ret	0
    ??$_Iter_random@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@std@@YA?AUrandom_access_iterator_tag@0@ABV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z ENDP ; std::_Iter_random<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> > >
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z
    _TEXT	SEGMENT
    ??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z PROC ; std::_Checked_base<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> > >, COMDAT
    ; __It$ = eax
    
    ; 1164 : 		typename _Checked_iterator_base_helper<_Iter>::_Checked_iterator_base_type_tag _Base_tag;
    ; 1165 : 		return _Checked_base(_It, _Base_tag);
    
    	mov	eax, DWORD PTR [eax+4]
    
    ; 1166 : 	}
    
    	ret	0
    ??$_Checked_base@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@YAPADAAV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z ENDP ; std::_Checked_base<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> > >
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\ostream
    _TEXT	ENDS
    ;	COMDAT ??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ
    _TEXT	SEGMENT
    ??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ PROC ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::~_Sentry_base, COMDAT
    ; _this$ = eax
    
    ; 82   : 			if (_Myostr.rdbuf() != 0)
    
    	mov	eax, DWORD PTR [eax]
    	mov	ecx, DWORD PTR [eax]
    	mov	edx, DWORD PTR [ecx+4]
    	mov	eax, DWORD PTR [edx+eax+40]
    	test	eax, eax
    	je	SHORT $LN1@Sentry_bas
    
    ; 83   : 				_Myostr.rdbuf()->_Unlock();
    
    	mov	ecx, eax
    	jmp	DWORD PTR __imp_?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN1@Sentry_bas:
    
    ; 84   : 			}
    
    	ret	0
    ??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ENDP ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::~_Sentry_base
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??0_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z
    _TEXT	SEGMENT
    ??0_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z PROC ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base, COMDAT
    ; _this$ = esi
    ; __Ostr$ = eax
    
    ; 75   : 			{	// lock the stream buffer, if there
    
    	mov	DWORD PTR [esi], eax
    
    ; 76   : 			if (_Myostr.rdbuf() != 0)
    
    	mov	ecx, DWORD PTR [eax]
    	mov	edx, DWORD PTR [ecx+4]
    	mov	eax, DWORD PTR [edx+eax+40]
    	test	eax, eax
    	je	SHORT $LN8@Sentry_bas@2
    
    ; 77   : 				_Myostr.rdbuf()->_Lock();
    
    	mov	ecx, eax
    	call	DWORD PTR __imp_?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN8@Sentry_bas@2:
    
    ; 78   : 			}
    
    	mov	eax, esi
    	ret	0
    ??0_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z ENDP ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??Bsentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QBE_NXZ
    _TEXT	SEGMENT
    ??Bsentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QBE_NXZ PROC ; std::basic_ostream<char,std::char_traits<char> >::sentry::operator bool, COMDAT
    ; _this$ = eax
    
    ; 116  : 			return (_Ok);
    
    	mov	al, BYTE PTR [eax+4]
    
    ; 117  : 			}
    
    	ret	0
    ??Bsentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QBE_NXZ ENDP ; std::basic_ostream<char,std::char_traits<char> >::sentry::operator bool
    _TEXT	ENDS
    EXTRN	___security_cookie:DWORD
    EXTRN	___CxxFrameHandler3:PROC
    ;	COMDAT xdata$x
    ; File c:\programme\microsoft visual studio 9.0\vc\include\ios
    xdata$x	SEGMENT
    __unwindtable$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ DD 0ffffffffH
    	DD	FLAT:__unwindfunclet$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ$0
    __ehfuncinfo$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ DD 019930522H
    	DD	01H
    	DD	FLAT:__unwindtable$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ
    	DD	2 DUP(00H)
    	DD	2 DUP(00H)
    	DD	00H
    	DD	01H
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\ostream
    xdata$x	ENDS
    ;	COMDAT ??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ
    _TEXT	SEGMENT
    __$EHRec$ = -12						; size = 12
    _this$ = 8						; size = 4
    ??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ PROC ; std::basic_ostream<char,std::char_traits<char> >::sentry::~sentry, COMDAT
    
    ; 102  : 			{	// destroy the object
    
    	push	-1
    	push	__ehhandler$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ
    	mov	eax, DWORD PTR fs:0
    	push	eax
    	push	esi
    	mov	eax, DWORD PTR ___security_cookie
    	xor	eax, esp
    	push	eax
    	lea	eax, DWORD PTR __$EHRec$[esp+20]
    	mov	DWORD PTR fs:0, eax
    	mov	esi, DWORD PTR _this$[esp+16]
    	mov	DWORD PTR __$EHRec$[esp+28], 0
    
    ; 103  : 
    ; 104  :  #if _HAS_EXCEPTIONS
    ; 105  : 			if (!_XSTD uncaught_exception())
    
    	call	DWORD PTR __imp_?uncaught_exception@std@@YA_NXZ
    	test	al, al
    	jne	SHORT $LN1@sentry
    
    ; 106  : 				this->_Myostr._Osfx();
    
    	mov	ecx, DWORD PTR [esi]
    	call	DWORD PTR __imp_?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN1@sentry:
    
    ; 107  : 			}
    
    	mov	DWORD PTR __$EHRec$[esp+28], -1
    	mov	eax, DWORD PTR [esi]
    	mov	ecx, DWORD PTR [eax]
    	mov	edx, DWORD PTR [ecx+4]
    	mov	eax, DWORD PTR [edx+eax+40]
    	test	eax, eax
    	je	SHORT $LN5@sentry
    	mov	ecx, eax
    	call	DWORD PTR __imp_?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN5@sentry:
    	mov	ecx, DWORD PTR __$EHRec$[esp+20]
    	mov	DWORD PTR fs:0, ecx
    	pop	ecx
    	pop	esi
    	add	esp, 12					; 0000000cH
    	ret	4
    _TEXT	ENDS
    ;	COMDAT text$x
    text$x	SEGMENT
    __unwindfunclet$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ$0:
    	mov	eax, DWORD PTR _this$[ebp-4]
    	jmp	??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::~_Sentry_base
    __ehhandler$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ:
    	mov	edx, DWORD PTR [esp+8]
    	lea	eax, DWORD PTR [edx-4]
    	mov	ecx, DWORD PTR [edx-8]
    	xor	ecx, eax
    	call	@__security_check_cookie@4
    	mov	eax, OFFSET __ehfuncinfo$??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ
    	jmp	___CxxFrameHandler3
    text$x	ENDS
    ??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ENDP ; std::basic_ostream<char,std::char_traits<char> >::sentry::~sentry
    ;	COMDAT xdata$x
    ; File c:\programme\microsoft visual studio 9.0\vc\include\xiosbase
    xdata$x	SEGMENT
    __unwindtable$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z DD 0ffffffffH
    	DD	FLAT:__unwindfunclet$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z$0
    __ehfuncinfo$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z DD 019930522H
    	DD	01H
    	DD	FLAT:__unwindtable$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z
    	DD	2 DUP(00H)
    	DD	2 DUP(00H)
    	DD	00H
    	DD	01H
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\ostream
    xdata$x	ENDS
    ;	COMDAT ??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z
    _TEXT	SEGMENT
    __$EHRec$ = -12						; size = 12
    _this$ = 8						; size = 4
    ??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z PROC ; std::basic_ostream<char,std::char_traits<char> >::sentry::sentry, COMDAT
    ; __Ostr$ = esi
    
    ; 95   : 			{	// construct locking and testing stream
    
    	push	-1
    	push	__ehhandler$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z
    	mov	eax, DWORD PTR fs:0
    	push	eax
    	push	edi
    	mov	eax, DWORD PTR ___security_cookie
    	xor	eax, esp
    	push	eax
    	lea	eax, DWORD PTR __$EHRec$[esp+20]
    	mov	DWORD PTR fs:0, eax
    	mov	edi, DWORD PTR _this$[esp+16]
    	mov	DWORD PTR [edi], esi
    	mov	eax, DWORD PTR [esi]
    	mov	ecx, DWORD PTR [eax+4]
    	mov	ecx, DWORD PTR [ecx+esi+40]
    	test	ecx, ecx
    	je	SHORT $LN5@sentry@2
    	call	DWORD PTR __imp_?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN5@sentry@2:
    	mov	DWORD PTR __$EHRec$[esp+28], 0
    
    ; 96   : 			if (_Ostr.good() && _Ostr.tie() != 0)
    
    	mov	edx, DWORD PTR [esi]
    	mov	eax, DWORD PTR [edx+4]
    	add	eax, esi
    	cmp	DWORD PTR [eax+8], 0
    	jne	SHORT $LN1@sentry@2
    	mov	eax, DWORD PTR [eax+44]
    	test	eax, eax
    	je	SHORT $LN1@sentry@2
    
    ; 97   : 				_Ostr.tie()->flush();
    
    	mov	ecx, eax
    	call	DWORD PTR __imp_?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ
    $LN1@sentry@2:
    
    ; 98   : 			_Ok = _Ostr.good();	// store test only after flushing tie
    
    	mov	ecx, DWORD PTR [esi]
    	mov	edx, DWORD PTR [ecx+4]
    	cmp	DWORD PTR [edx+esi+8], 0
    	sete	al
    	mov	BYTE PTR [edi+4], al
    
    ; 99   : 			}
    
    	mov	eax, edi
    	mov	ecx, DWORD PTR __$EHRec$[esp+20]
    	mov	DWORD PTR fs:0, ecx
    	pop	ecx
    	pop	edi
    	add	esp, 12					; 0000000cH
    	ret	4
    _TEXT	ENDS
    ;	COMDAT text$x
    text$x	SEGMENT
    __unwindfunclet$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z$0:
    	mov	eax, DWORD PTR _this$[ebp-4]
    	jmp	??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::~_Sentry_base
    __ehhandler$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z:
    	mov	edx, DWORD PTR [esp+8]
    	lea	eax, DWORD PTR [edx-4]
    	mov	ecx, DWORD PTR [edx-8]
    	xor	ecx, eax
    	call	@__security_check_cookie@4
    	mov	eax, OFFSET __ehfuncinfo$??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z
    	jmp	___CxxFrameHandler3
    text$x	ENDS
    ??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z ENDP ; std::basic_ostream<char,std::char_traits<char> >::sentry::sentry
    ; Function compile flags: /Ogtpy
    ; File x:\main.cpp
    ;	COMDAT ?rot13@@YADD@Z
    _TEXT	SEGMENT
    _c$ = 8							; size = 1
    ?rot13@@YADD@Z PROC					; rot13, COMDAT
    
    ; 7    :     return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13);
    
    	mov	al, BYTE PTR _c$[esp-4]
    	not	al
    	push	esi
    	movsx	esi, al
    	mov	ecx, esi
    	or	ecx, 32					; 00000020H
    	not	ecx
    	mov	eax, 1321528399				; 4ec4ec4fH
    	imul	ecx
    	sar	edx, 2
    	mov	eax, edx
    	shr	eax, 31					; 0000001fH
    	add	eax, edx
    	lea	ecx, DWORD PTR [eax+eax-11]
    	mov	eax, 1
    	cdq
    	idiv	ecx
    	mov	edx, eax
    	imul	edx, 13					; 0000000dH
    	mov	eax, esi
    	not	eax
    	sub	eax, edx
    	pop	esi
    
    ; 8    : }
    
    	ret	0
    ?rot13@@YADD@Z ENDP					; rot13
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\xutility
    _TEXT	ENDS
    ;	COMDAT ?_Has_container@_Iterator_base_secure@std@@QBE_NXZ
    _TEXT	SEGMENT
    ?_Has_container@_Iterator_base_secure@std@@QBE_NXZ PROC	; std::_Iterator_base_secure::_Has_container, COMDAT
    ; _this$ = ecx
    
    ; 582  : 		return _Mycont != 0;
    
    	xor	eax, eax
    	cmp	DWORD PTR [ecx], eax
    	setne	al
    
    ; 583  : 		}
    
    	ret	0
    ?_Has_container@_Iterator_base_secure@std@@QBE_NXZ ENDP	; std::_Iterator_base_secure::_Has_container
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\xstring
    _TEXT	ENDS
    ;	COMDAT ??Y?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z
    _TEXT	SEGMENT
    ??Y?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z PROC ; std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=, COMDAT
    ; _this$ = esi
    ; __Off$ = ebx
    
    ; 170  : 		if (this->_Mycont != _IGNORE_MYCONT)
    
    	mov	eax, DWORD PTR [esi]
    	cmp	eax, -4					; fffffffcH
    	je	SHORT $LN2@operator
    
    ; 171  : 		{
    ; 172  : 			_SCL_SECURE_VALIDATE(this->_Has_container());
    
    	test	eax, eax
    	jne	SHORT $LN3@operator
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN3@operator:
    
    ; 173  : 			_SCL_SECURE_VALIDATE_RANGE(
    
    	mov	eax, DWORD PTR [esi]
    	cmp	DWORD PTR [eax+24], 16			; 00000010H
    	jb	SHORT $LN11@operator
    	mov	edx, DWORD PTR [eax+4]
    	jmp	SHORT $LN12@operator
    $LN11@operator:
    	lea	edx, DWORD PTR [eax+4]
    $LN12@operator:
    	mov	ecx, DWORD PTR [esi+4]
    	push	ebp
    	mov	ebp, DWORD PTR [eax+20]
    	add	ebp, edx
    	add	ecx, ebx
    	cmp	ecx, ebp
    	pop	ebp
    	ja	SHORT $LN1@operator
    	cmp	DWORD PTR [eax+24], 16			; 00000010H
    	jb	SHORT $LN15@operator
    	mov	eax, DWORD PTR [eax+4]
    	jmp	SHORT $LN16@operator
    $LN15@operator:
    	add	eax, 4
    $LN16@operator:
    	cmp	ecx, eax
    	jae	SHORT $LN2@operator
    $LN1@operator:
    
    ; 174  : 				_Myptr + _Off <= (((_Mystring *)this->_Mycont)->_Myptr() + ((_Mystring *)this->_Mycont)->_Mysize) &&
    ; 175  : 				_Myptr + _Off >= ((_Mystring *)this->_Mycont)->_Myptr());
    
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN2@operator:
    
    ; 176  : 		}
    ; 177  : 		_Myptr += _Off;
    
    	add	DWORD PTR [esi+4], ebx
    
    ; 178  : 		return (*this);
    
    	mov	eax, esi
    
    ; 179  : 		}
    
    	ret	0
    ??Y?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z ENDP ; std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??Y?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z
    _TEXT	SEGMENT
    ??Y?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z PROC ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=, COMDAT
    ; _this$ = esi
    ; __Off$ = ebx
    
    ; 405  : 		(*(_Mybase *)this) += _Off;
    
    	mov	eax, DWORD PTR [esi]
    	cmp	eax, -4					; fffffffcH
    	je	SHORT $LN4@operator@2
    	test	eax, eax
    	jne	SHORT $LN5@operator@2
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN5@operator@2:
    	mov	eax, DWORD PTR [esi]
    	cmp	DWORD PTR [eax+24], 16			; 00000010H
    	jb	SHORT $LN13@operator@2
    	mov	edx, DWORD PTR [eax+4]
    	jmp	SHORT $LN14@operator@2
    $LN13@operator@2:
    	lea	edx, DWORD PTR [eax+4]
    $LN14@operator@2:
    	mov	ecx, DWORD PTR [esi+4]
    	push	ebp
    	mov	ebp, DWORD PTR [eax+20]
    	add	ebp, edx
    	add	ecx, ebx
    	cmp	ecx, ebp
    	pop	ebp
    	ja	SHORT $LN3@operator@2
    	cmp	DWORD PTR [eax+24], 16			; 00000010H
    	jb	SHORT $LN17@operator@2
    	mov	eax, DWORD PTR [eax+4]
    	jmp	SHORT $LN18@operator@2
    $LN17@operator@2:
    	add	eax, 4
    $LN18@operator@2:
    	cmp	ecx, eax
    	jae	SHORT $LN4@operator@2
    $LN3@operator@2:
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN4@operator@2:
    	add	DWORD PTR [esi+4], ebx
    
    ; 406  : 		return (*this);
    
    	mov	eax, esi
    
    ; 407  : 		}
    
    	ret	0
    ??Y?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@H@Z ENDP ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??H?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV01@H@Z
    _TEXT	SEGMENT
    ___$ReturnUdt$ = 8					; size = 4
    __Off$ = 12						; size = 4
    ??H?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV01@H@Z PROC ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+, COMDAT
    ; _this$ = eax
    
    ; 410  : 		{	// return this + integer
    
    	push	ebx
    	push	ebp
    	push	esi
    
    ; 411  : 		_Myt _Tmp = *this;
    
    	mov	esi, DWORD PTR [eax]
    	push	edi
    	mov	edi, DWORD PTR [eax+4]
    
    ; 412  : 		return (_Tmp += _Off);
    
    	cmp	esi, -4					; fffffffcH
    	je	SHORT $LN6@operator@3
    	test	esi, esi
    	jne	SHORT $LN7@operator@3
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN7@operator@3:
    	mov	ebx, DWORD PTR [esi+24]
    	lea	eax, DWORD PTR [esi+4]
    	cmp	ebx, 16					; 00000010H
    	jb	SHORT $LN15@operator@3
    	mov	ecx, DWORD PTR [eax]
    	jmp	SHORT $LN16@operator@3
    $LN15@operator@3:
    	mov	ecx, eax
    $LN16@operator@3:
    	mov	edx, DWORD PTR __Off$[esp+12]
    	mov	ebp, DWORD PTR [esi+20]
    	add	edx, edi
    	add	ebp, ecx
    	cmp	edx, ebp
    	ja	SHORT $LN5@operator@3
    	cmp	ebx, 16					; 00000010H
    	jb	SHORT $LN19@operator@3
    	mov	eax, DWORD PTR [eax]
    $LN19@operator@3:
    	cmp	edx, eax
    	jae	SHORT $LN6@operator@3
    $LN5@operator@3:
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN6@operator@3:
    	add	edi, DWORD PTR __Off$[esp+12]
    	mov	eax, DWORD PTR ___$ReturnUdt$[esp+12]
    	mov	DWORD PTR [eax+4], edi
    
    ; 413  : 		}
    
    	pop	edi
    	mov	DWORD PTR [eax], esi
    	pop	esi
    	pop	ebp
    	pop	ebx
    	ret	8
    ??H?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV01@H@Z ENDP ; std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\algorithm
    _TEXT	ENDS
    ;	COMDAT ??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z
    _TEXT	SEGMENT
    ___$ReturnUdt$ = 8					; size = 4
    __First$ = 12						; size = 4
    __Last$ = 16						; size = 4
    ___formal$ = 20						; size = 1
    ___formal$ = 24						; size = 1
    __Dest$ = 28						; size = 8
    ??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z PROC ; std::_Transform<char *,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>, COMDAT
    
    ; 678  : 	{	// transform [_First, _Last) with _Func
    
    	push	ebx
    
    ; 679  : 	// for range checked iterators, this will make sure there is enough space
    ; 680  : 	_OutIt _Result = _Dest + (_Last - _First);
    
    	mov	ebx, DWORD PTR __Dest$[esp]
    	push	ebp
    	mov	ebp, DWORD PTR __First$[esp+4]
    	push	esi
    	mov	esi, DWORD PTR __Dest$[esp+12]
    	push	edi
    	mov	edi, DWORD PTR __Last$[esp+12]
    	sub	edi, ebp
    	cmp	ebx, -4					; fffffffcH
    	je	SHORT $LN8@Transform@2
    	test	ebx, ebx
    	jne	SHORT $LN9@Transform@2
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN9@Transform@2:
    	mov	eax, DWORD PTR [ebx+24]
    	cmp	eax, 16					; 00000010H
    	lea	eax, DWORD PTR [ebx+4]
    	jb	SHORT $LN17@Transform@2
    	mov	ecx, DWORD PTR [eax]
    	jmp	SHORT $LN18@Transform@2
    $LN17@Transform@2:
    	mov	ecx, eax
    $LN18@Transform@2:
    	mov	edx, DWORD PTR [ebx+20]
    	add	edx, ecx
    	lea	ecx, DWORD PTR [esi+edi]
    	cmp	ecx, edx
    	ja	SHORT $LN7@Transform@2
    	cmp	DWORD PTR [ebx+24], 16			; 00000010H
    	jb	SHORT $LN21@Transform@2
    	mov	eax, DWORD PTR [eax]
    $LN21@Transform@2:
    	cmp	ecx, eax
    	jae	SHORT $LN8@Transform@2
    $LN7@Transform@2:
    	call	DWORD PTR __imp___invalid_parameter_noinfo
    $LN8@Transform@2:
    	mov	eax, DWORD PTR ___$ReturnUdt$[esp+12]
    	add	esi, edi
    
    ; 681  : 	_Transform(_First, _Last, _CHECKED_BASE(_Dest), _Func,
    ; 682  : 		forward_iterator_tag(), _Range_checked_iterator_tag());
    
    	mov	edi, DWORD PTR __Dest$[esp+16]
    	mov	DWORD PTR [eax+4], esi
    	mov	DWORD PTR [eax], ebx
    	mov	esi, ebp
    	cmp	ebp, DWORD PTR __Last$[esp+12]
    	je	SHORT $LN29@Transform@2
    	npad	5
    $LL31@Transform@2:
    	movzx	eax, BYTE PTR [esi]
    	push	eax
    	call	?rot13@@YADD@Z				; rot13
    	mov	BYTE PTR [edi], al
    	inc	esi
    	add	esp, 4
    	inc	edi
    	cmp	esi, DWORD PTR __Last$[esp+12]
    	jne	SHORT $LL31@Transform@2
    
    ; 683  : 	return (_Result);
    
    	mov	eax, DWORD PTR ___$ReturnUdt$[esp+12]
    
    ; 681  : 	_Transform(_First, _Last, _CHECKED_BASE(_Dest), _Func,
    ; 682  : 		forward_iterator_tag(), _Range_checked_iterator_tag());
    
    $LN29@Transform@2:
    
    ; 684  : 	}
    
    	pop	edi
    	pop	esi
    	pop	ebp
    	pop	ebx
    	ret	0
    ??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ENDP ; std::_Transform<char *,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    ; Function compile flags: /Ogtpy
    _TEXT	ENDS
    ;	COMDAT ??$transform@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@V10@00P6ADD@Z@Z
    _TEXT	SEGMENT
    $T28274 = -4						; size = 1
    __First$ = 8						; size = 8
    $T28275 = 16						; size = 1
    __Last$ = 16						; size = 8
    __Dest$ = 24						; size = 8
    ??$transform@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@V10@00P6ADD@Z@Z PROC ; std::transform<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>, COMDAT
    ; ___$ReturnUdt$ = esi
    
    ; 692  : 	{
    
    	push	ecx
    
    ; 693  : 	return _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
    ; 694  : 		_Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
    
    	mov	eax, DWORD PTR __Dest$[esp+4]
    	mov	ecx, DWORD PTR __Dest$[esp]
    	push	eax
    	mov	eax, DWORD PTR $T28275[esp+4]
    	push	ecx
    	mov	ecx, DWORD PTR __Last$[esp+12]
    	mov	BYTE PTR $T28274[esp+12], 0
    	mov	edx, DWORD PTR $T28274[esp+12]
    	push	edx
    	mov	edx, DWORD PTR __First$[esp+16]
    	push	eax
    	push	ecx
    	push	edx
    	push	esi
    	call	??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ; std::_Transform<char *,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    	mov	eax, esi
    
    ; 695  : 	}
    
    	add	esp, 32					; 00000020H
    	ret	0
    ??$transform@V?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@V10@00P6ADD@Z@Z ENDP ; std::transform<std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    _TEXT	ENDS
    ;	COMDAT xdata$x
    ; File c:\programme\microsoft visual studio 9.0\vc\include\ios
    xdata$x	SEGMENT
    __unwindtable$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z DD 0ffffffffH
    	DD	FLAT:__unwindfunclet$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$2
    	DD	00H
    	DD	00H
    	DD	00H
    	DD	00H
    	DD	0ffffffffH
    	DD	FLAT:__unwindfunclet$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$3
    __catchsym$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$4 DD 040H
    	DD	00H
    	DD	00H
    	DD	FLAT:__catch$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$0
    __tryblocktable$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z DD 01H
    	DD	01H
    	DD	02H
    	DD	01H
    	DD	FLAT:__catchsym$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$4
    __ehfuncinfo$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z DD 019930522H
    	DD	04H
    	DD	FLAT:__unwindtable$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
    	DD	01H
    	DD	FLAT:__tryblocktable$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
    	DD	2 DUP(00H)
    	DD	00H
    	DD	01H
    ; Function compile flags: /Ogtpy
    ; File c:\programme\microsoft visual studio 9.0\vc\include\ostream
    xdata$x	ENDS
    ;	COMDAT ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
    _TEXT	SEGMENT
    __Ok$ = -32						; size = 8
    $T28373 = -24						; size = 1
    $T28355 = -24						; size = 1
    __State$ = -20						; size = 4
    __$EHRec$ = -16						; size = 16
    __Ostr$ = 8						; size = 4
    __Val$ = 12						; size = 4
    ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z PROC ; std::operator<<<std::char_traits<char> >, COMDAT
    
    ; 741  : 	{	// insert NTBS into char stream
    
    	push	ebp
    	mov	ebp, esp
    	push	-1
    	push	__ehhandler$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
    	mov	eax, DWORD PTR fs:0
    	push	eax
    	sub	esp, 20					; 00000014H
    	push	ebx
    	push	esi
    	push	edi
    	mov	eax, DWORD PTR ___security_cookie
    	xor	eax, ebp
    	push	eax
    	lea	eax, DWORD PTR __$EHRec$[ebp+4]
    	mov	DWORD PTR fs:0, eax
    	mov	DWORD PTR __$EHRec$[ebp], esp
    	mov	esi, DWORD PTR __Ostr$[ebp]
    
    ; 742  : 	typedef char _Elem;
    ; 743  : 	typedef basic_ostream<_Elem, _Traits> _Myos;
    ; 744  : 	ios_base::iostate _State = ios_base::goodbit;
    ; 745  : 	streamsize _Count = (streamsize)_Traits::length(_Val);	// may overflow
    
    	mov	eax, DWORD PTR __Val$[ebp]
    	xor	ebx, ebx
    	mov	DWORD PTR __State$[ebp], ebx
    	lea	edx, DWORD PTR [eax+1]
    	npad	7
    $LL72@operator@4:
    	mov	cl, BYTE PTR [eax]
    	inc	eax
    	test	cl, cl
    	jne	SHORT $LL72@operator@4
    	sub	eax, edx
    	mov	edi, eax
    
    ; 746  : 	streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count
    ; 747  : 		? 0 : _Ostr.width() - _Count;
    
    	mov	eax, DWORD PTR [esi]
    	mov	ecx, DWORD PTR [eax+4]
    	mov	eax, DWORD PTR [ecx+esi+24]
    	cmp	eax, ebx
    	jle	SHORT $LN17@operator@4
    	cmp	eax, edi
    	jle	SHORT $LN17@operator@4
    	sub	eax, edi
    	mov	ebx, eax
    $LN17@operator@4:
    
    ; 748  : 	const typename _Myos::sentry _Ok(_Ostr);
    
    	lea	edx, DWORD PTR __Ok$[ebp]
    	push	edx
    	call	??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@AAV12@@Z ; std::basic_ostream<char,std::char_traits<char> >::sentry::sentry
    	mov	DWORD PTR __$EHRec$[ebp+12], 0
    
    ; 749  : 
    ; 750  : 	if (!_Ok)
    
    	cmp	BYTE PTR __Ok$[ebp+4], 0
    	jne	SHORT $LN14@operator@4
    
    ; 751  : 		_State |= ios_base::badbit;
    
    	mov	DWORD PTR __State$[ebp], 4
    
    ; 752  : 	else
    
    	jmp	SHORT $LN22@operator@4
    $LN14@operator@4:
    
    ; 753  : 		{	// state okay, insert
    ; 754  : 		_TRY_IO_BEGIN
    
    	mov	BYTE PTR __$EHRec$[ebp+12], 1
    
    ; 755  : 		if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left)
    
    	mov	eax, DWORD PTR [esi]
    	mov	ecx, DWORD PTR [eax+4]
    	mov	eax, DWORD PTR [ecx+esi+16]
    	and	eax, 448				; 000001c0H
    	cmp	eax, 64					; 00000040H
    	je	SHORT $LN70@operator@4
    $LL10@operator@4:
    
    ; 756  : 			for (; 0 < _Pad; --_Pad)	// pad on left
    
    	test	ebx, ebx
    	jle	SHORT $LN8@operator@4
    
    ; 757  : 				if (_Traits::eq_int_type(_Traits::eof(),
    ; 758  : 					_Ostr.rdbuf()->sputc(_Ostr.fill())))
    
    	mov	edx, DWORD PTR [esi]
    	mov	eax, DWORD PTR [edx+4]
    	mov	cl, BYTE PTR [eax+esi+48]
    	add	eax, esi
    	mov	eax, DWORD PTR [eax+40]
    	mov	BYTE PTR $T28355[ebp], cl
    	mov	edx, DWORD PTR $T28355[ebp]
    	push	edx
    	mov	ecx, eax
    	call	DWORD PTR __imp_?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z
    	cmp	eax, -1
    	jne	$LN9@operator@4
    
    ; 759  : 					{	// insertion failed, quit
    ; 760  : 					_State |= ios_base::badbit;
    
    	or	DWORD PTR __State$[ebp], 4
    $LN8@operator@4:
    
    ; 761  : 					break;
    ; 762  : 					}
    ; 763  : 
    ; 764  : 		if (_State == ios_base::goodbit
    ; 765  : 			&& _Ostr.rdbuf()->sputn(_Val, _Count) != _Count)
    
    	cmp	DWORD PTR __State$[ebp], 0
    	jne	SHORT $LN2@operator@4
    $LN70@operator@4:
    	mov	eax, DWORD PTR [esi]
    	mov	ecx, DWORD PTR [eax+4]
    	mov	edx, DWORD PTR __Val$[ebp]
    	mov	ecx, DWORD PTR [ecx+esi+40]
    	push	edi
    	push	edx
    	call	DWORD PTR __imp_?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHPBDH@Z
    	cmp	eax, edi
    	je	SHORT $LL71@operator@4
    
    ; 766  : 			_State |= ios_base::badbit;
    
    	mov	DWORD PTR __State$[ebp], 4
    $LN2@operator@4:
    
    ; 775  : 					}
    ; 776  : 		_Ostr.width(0);
    
    	mov	eax, DWORD PTR [esi]
    	mov	eax, DWORD PTR [eax+4]
    	add	eax, esi
    	xor	ecx, ecx
    	mov	DWORD PTR [eax+24], ecx
    	mov	DWORD PTR __$EHRec$[ebp+12], ecx
    $LN22@operator@4:
    
    ; 778  : 		}
    ; 779  : 
    ; 780  : 	_Ostr.setstate(_State);
    
    	mov	ecx, DWORD PTR __State$[ebp]
    	mov	edx, DWORD PTR [esi]
    	push	0
    	push	ecx
    	mov	ecx, DWORD PTR [edx+4]
    	add	ecx, esi
    	call	DWORD PTR __imp_?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z
    
    ; 781  : 	return (_Ostr);
    
    	mov	DWORD PTR __$EHRec$[ebp+12], 3
    	call	DWORD PTR __imp_?uncaught_exception@std@@YA_NXZ
    	test	al, al
    	jne	SHORT $LN56@operator@4
    	mov	ecx, DWORD PTR __Ok$[ebp]
    	call	DWORD PTR __imp_?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN56@operator@4:
    	mov	DWORD PTR __$EHRec$[ebp+12], -1
    	mov	eax, DWORD PTR __Ok$[ebp]
    	mov	ecx, DWORD PTR [eax]
    	mov	edx, DWORD PTR [ecx+4]
    	mov	ecx, DWORD PTR [edx+eax+40]
    	test	ecx, ecx
    	je	SHORT $LN74@operator@4
    	call	DWORD PTR __imp_?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ
    $LN74@operator@4:
    	mov	eax, esi
    
    ; 782  : 	}
    
    	mov	ecx, DWORD PTR __$EHRec$[ebp+4]
    	mov	DWORD PTR fs:0, ecx
    	pop	ecx
    	pop	edi
    	pop	esi
    	pop	ebx
    	mov	esp, ebp
    	pop	ebp
    	ret	0
    $LN9@operator@4:
    
    ; 756  : 			for (; 0 < _Pad; --_Pad)	// pad on left
    
    	dec	ebx
    	jmp	$LL10@operator@4
    	npad	4
    $LL71@operator@4:
    
    ; 767  : 
    ; 768  : 		if (_State == ios_base::goodbit)
    ; 769  : 			for (; 0 < _Pad; --_Pad)	// pad on right
    
    	test	ebx, ebx
    	jle	SHORT $LN2@operator@4
    
    ; 770  : 				if (_Traits::eq_int_type(_Traits::eof(),
    ; 771  : 					_Ostr.rdbuf()->sputc(_Ostr.fill())))
    
    	mov	eax, DWORD PTR [esi]
    	mov	ecx, DWORD PTR [eax+4]
    	mov	dl, BYTE PTR [ecx+esi+48]
    	lea	eax, DWORD PTR [ecx+esi]
    	mov	eax, DWORD PTR [eax+40]
    	mov	BYTE PTR $T28373[ebp], dl
    	mov	ecx, DWORD PTR $T28373[ebp]
    	push	ecx
    	mov	ecx, eax
    	call	DWORD PTR __imp_?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z
    	cmp	eax, -1
    	jne	SHORT $LN3@operator@4
    
    ; 772  : 					{	// insertion failed, quit
    ; 773  : 					_State |= ios_base::badbit;
    
    	or	DWORD PTR __State$[ebp], 4
    
    ; 774  : 					break;
    
    	jmp	$LN2@operator@4
    $LN3@operator@4:
    
    ; 767  : 
    ; 768  : 		if (_State == ios_base::goodbit)
    ; 769  : 			for (; 0 < _Pad; --_Pad)	// pad on right
    
    	dec	ebx
    	jmp	SHORT $LL71@operator@4
    __catch$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$0:
    
    ; 777  : 		_CATCH_IO_(_Ostr)
    
    	mov	eax, DWORD PTR __Ostr$[ebp]
    	mov	edx, DWORD PTR [eax]
    	mov	ecx, DWORD PTR [edx+4]
    	push	1
    	push	4
    	add	ecx, eax
    	call	DWORD PTR __imp_?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z
    	mov	DWORD PTR __$EHRec$[ebp+12], 0
    	mov	eax, $LN23@operator@4
    	ret	0
    $LN23@operator@4:
    	mov	esi, DWORD PTR __Ostr$[ebp]
    	jmp	$LN22@operator@4
    _TEXT	ENDS
    ;	COMDAT text$x
    text$x	SEGMENT
    __unwindfunclet$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$2:
    	lea	eax, DWORD PTR __Ok$[ebp]
    	push	eax
    	call	??1sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ; std::basic_ostream<char,std::char_traits<char> >::sentry::~sentry
    	ret	0
    __unwindfunclet$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z$3:
    	lea	eax, DWORD PTR __Ok$[ebp]
    	jmp	??1_Sentry_base@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAE@XZ ; std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::~_Sentry_base
    __ehhandler$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z:
    	mov	edx, DWORD PTR [esp+8]
    	lea	eax, DWORD PTR [edx+12]
    	mov	ecx, DWORD PTR [edx-36]
    	xor	ecx, eax
    	call	@__security_check_cookie@4
    	mov	eax, OFFSET __ehfuncinfo$??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
    	jmp	___CxxFrameHandler3
    text$x	ENDS
    ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ENDP ; std::operator<<<std::char_traits<char> >
    PUBLIC	__$ArrayPad$
    PUBLIC	_main
    ;	COMDAT xdata$x
    ; File c:\programme\microsoft visual studio 9.0\vc\include\xstring
    xdata$x	SEGMENT
    __unwindtable$_main DD 0ffffffffH
    	DD	FLAT:__unwindfunclet$_main$0
    __ehfuncinfo$_main DD 019930522H
    	DD	01H
    	DD	FLAT:__unwindtable$_main
    	DD	2 DUP(00H)
    	DD	2 DUP(00H)
    	DD	00H
    	DD	01H
    ; Function compile flags: /Ogtpy
    ; File x:\main.cpp
    xdata$x	ENDS
    ;	COMDAT _main
    _TEXT	SEGMENT
    $T28557 = -88						; size = 1
    $T28558 = -88						; size = 1
    $T28492 = -88						; size = 1
    $T28493 = -88						; size = 1
    $T28576 = -88						; size = 8
    $T28511 = -88						; size = 8
    $T28577 = -80						; size = 8
    $T28512 = -80						; size = 8
    $T28446 = -80						; size = 8
    $T28442 = -80						; size = 8
    $T28445 = -72						; size = 8
    $T28439 = -72						; size = 8
    $T28443 = -64						; size = 8
    $T28441 = -64						; size = 8
    $T28444 = -56						; size = 8
    $T28440 = -56						; size = 8
    _buffer$ = -48						; size = 28
    __$ArrayPad$ = -20					; size = 4
    __$EHRec$ = -12						; size = 12
    _main	PROC						; COMDAT
    
    ; 11   : {
    
    	push	ebp
    	mov	ebp, esp
    	and	esp, -8					; fffffff8H
    	push	-1
    	push	__ehhandler$_main
    	mov	eax, DWORD PTR fs:0
    	push	eax
    	sub	esp, 80					; 00000050H
    	mov	eax, DWORD PTR ___security_cookie
    	xor	eax, esp
    	mov	DWORD PTR __$ArrayPad$[esp+92], eax
    	push	ebx
    	push	esi
    	push	edi
    	mov	eax, DWORD PTR ___security_cookie
    	xor	eax, esp
    	push	eax
    	lea	eax, DWORD PTR __$EHRec$[esp+108]
    	mov	DWORD PTR fs:0, eax
    
    ; 12   :     std::string buffer = "hallo, caeser rocks!";
    
    	push	OFFSET ??_C@_0BF@MBEGFLIL@hallo?0?5caeser?5rocks?$CB?$AA@
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	call	DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z
    	mov	DWORD PTR __$EHRec$[esp+116], 0
    
    ; 13   : 
    ; 14   :     // originial
    ; 15   :     std::cout << "Original: " << buffer << std::endl;
    
    	mov	eax, DWORD PTR __imp_?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z
    	mov	edx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
    	push	eax
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	push	ecx
    	push	OFFSET ??_C@_0L@EMJAFNHM@Original?3?5?$AA@
    	push	edx
    	call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    	mov	esi, DWORD PTR __imp_??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z
    	add	esp, 8
    	push	eax
    	call	esi
    	add	esp, 8
    	mov	ecx, eax
    	call	DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z
    
    ; 16   : 
    ; 17   :     // encoding
    ; 18   :     std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13);
    
    	lea	eax, DWORD PTR $T28439[esp+108]
    	push	eax
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	call	DWORD PTR __imp_?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ
    	mov	edi, DWORD PTR [eax]
    	mov	ebx, DWORD PTR [eax+4]
    	lea	ecx, DWORD PTR $T28440[esp+108]
    	push	ecx
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	call	DWORD PTR __imp_?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ
    	mov	edx, DWORD PTR [eax]
    	mov	eax, DWORD PTR [eax+4]
    	lea	ecx, DWORD PTR $T28441[esp+108]
    	push	ecx
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	mov	DWORD PTR $T28512[esp+112], edx
    	mov	DWORD PTR $T28512[esp+116], eax
    	call	DWORD PTR __imp_?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ
    	mov	edx, DWORD PTR [eax]
    	mov	eax, DWORD PTR [eax+4]
    	push	ebx
    	mov	DWORD PTR $T28511[esp+112], edx
    	push	edi
    	mov	BYTE PTR $T28492[esp+116], 0
    	mov	ecx, DWORD PTR $T28492[esp+116]
    	mov	edx, DWORD PTR $T28493[esp+116]
    	push	ecx
    	mov	ecx, DWORD PTR $T28512[esp+124]
    	push	edx
    	push	ecx
    	push	eax
    	lea	edx, DWORD PTR $T28442[esp+132]
    	push	edx
    	call	??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ; std::_Transform<char *,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    
    ; 19   :     std::cout << "Encoded:  " << buffer << std::endl;
    
    	mov	eax, DWORD PTR __imp_?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z
    	mov	edx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
    	add	esp, 28					; 0000001cH
    	push	eax
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	push	ecx
    	push	OFFSET ??_C@_0L@OJEBJNBO@Encoded?3?5?5?$AA@
    	push	edx
    	call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    	add	esp, 8
    	push	eax
    	call	esi
    	add	esp, 8
    	mov	ecx, eax
    	call	DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z
    
    ; 20   : 
    ; 21   :     // decoding
    ; 22   :     std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13);
    
    	lea	eax, DWORD PTR $T28443[esp+108]
    	push	eax
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	call	DWORD PTR __imp_?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ
    	mov	edi, DWORD PTR [eax]
    	mov	ebx, DWORD PTR [eax+4]
    	lea	ecx, DWORD PTR $T28444[esp+108]
    	push	ecx
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	call	DWORD PTR __imp_?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ
    	mov	edx, DWORD PTR [eax]
    	mov	DWORD PTR $T28577[esp+108], edx
    	mov	eax, DWORD PTR [eax+4]
    	lea	ecx, DWORD PTR $T28445[esp+108]
    	push	ecx
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	mov	DWORD PTR $T28577[esp+116], eax
    	call	DWORD PTR __imp_?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ
    	mov	edx, DWORD PTR [eax]
    	mov	eax, DWORD PTR [eax+4]
    	push	ebx
    	mov	DWORD PTR $T28576[esp+112], edx
    	push	edi
    	mov	BYTE PTR $T28557[esp+116], 0
    	mov	ecx, DWORD PTR $T28557[esp+116]
    	mov	edx, DWORD PTR $T28558[esp+116]
    	push	ecx
    	mov	ecx, DWORD PTR $T28577[esp+124]
    	push	edx
    	push	ecx
    	push	eax
    	lea	edx, DWORD PTR $T28446[esp+132]
    	push	edx
    	call	??$_Transform@PADV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@P6ADD@Z@std@@YA?AV?$_String_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PAD0V10@P6ADD@ZUrandom_access_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z ; std::_Transform<char *,std::_String_iterator<char,std::char_traits<char>,std::allocator<char> >,char (__cdecl*)(char)>
    
    ; 23   :     std::cout << "Decoded:  " << buffer << std::endl;
    
    	mov	eax, DWORD PTR __imp_?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z
    	mov	edx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
    	add	esp, 28					; 0000001cH
    	push	eax
    	lea	ecx, DWORD PTR _buffer$[esp+112]
    	push	ecx
    	push	OFFSET ??_C@_0L@NACPLJCJ@Decoded?3?5?5?$AA@
    	push	edx
    	call	??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    	add	esp, 8
    	push	eax
    	call	esi
    	add	esp, 8
    	mov	ecx, eax
    	call	DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z
    
    ; 24   : 
    ; 25   :     return 0;
    
    	lea	ecx, DWORD PTR _buffer$[esp+108]
    	mov	DWORD PTR __$EHRec$[esp+116], -1
    	call	DWORD PTR __imp_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ
    	xor	eax, eax
    
    ; 26   : } 
    
    	mov	ecx, DWORD PTR __$EHRec$[esp+108]
    	mov	DWORD PTR fs:0, ecx
    	pop	ecx
    	pop	edi
    	pop	esi
    	pop	ebx
    	mov	ecx, DWORD PTR __$ArrayPad$[esp+92]
    	xor	ecx, esp
    	call	@__security_check_cookie@4
    	mov	esp, ebp
    	pop	ebp
    	ret	0
    _TEXT	ENDS
    ;	COMDAT text$x
    text$x	SEGMENT
    __unwindfunclet$_main$0:
    	lea	ecx, DWORD PTR _buffer$[ebp]
    	jmp	DWORD PTR __imp_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ
    __ehhandler$_main:
    	mov	edx, DWORD PTR [esp+8]
    	lea	eax, DWORD PTR [edx-92]
    	mov	ecx, DWORD PTR [edx-96]
    	xor	ecx, eax
    	call	@__security_check_cookie@4
    	add	eax, 12					; 0000000cH
    	mov	ecx, DWORD PTR [edx-8]
    	xor	ecx, eax
    	call	@__security_check_cookie@4
    	mov	eax, OFFSET __ehfuncinfo$_main
    	jmp	___CxxFrameHandler3
    text$x	ENDS
    _main	ENDP
    END
    

    Gruß,
    unsigned long



  • "Jede Anweisung kostet Zeit."

    genau - und mir ist es total wichtig, dass die Ausgabe mind. 1Mrd Zeichen pro Sekunde schafft - sonst langweile ich mich ja beim Lesen...


  • Administrator

    unsigned long schrieb:

    Ich denke mal, dass dieser Bände ´für sich spricht, wenn man als Faustregel folgende nimmt: "Jede Anweisung kostet Zeit."

    Ich denke mal, dass dies Bände für sich spricht, dass du den Assembleroutput nicht gelesen oder verstanden hast.

    Ein Grossteil davon kommt durch die Iostreams, über welche wir gar nicht gesprochen haben, und der andere Teil durch den std::string .

    Edit: Über diesen Satz bin ich mir gar nicht mehr sicher:
    "Die std::transform Funktionen werden, wie man sehr schön sehen kann, völlig wegoptimiert."
    Mein Wissen über Assembler ist auch nur begrenzt. Trotzdem gilt das nachfolgende immer noch.

    Ich sage es nochmals, man kann nur sinnvoll über Performance argumentieren, wenn man einen Profiler nimmt. Aber du scheinst dich lieber auf dein Halbwissen und deine Abschätzungen zu verlassen ...

    Grüssli



  • unsigned long schrieb:

    ...also ich war einfach mal so frei, die beiden Sources durch den aktuellen VC++2008 SP1 Compiler zu jagen (Standard Release, normale Optimierungen auf Speed, Multi-Threaded DLL) und mal den Assembler-Output anzuzeigen. ...

    Vorab: Ich bin kein Profi ...
    ....aber mir sieht das sehr danach aus, als ob Du da das Object zeigst.

    Das hier z.B.: lässt mich das vermuten:

    unsigned long schrieb:

    ; 21   :     printf ("decoded: %s\n", buffer);
    
        lea    eax, DWORD PTR _buffer$[esp+44]
        push    eax
        push    OFFSET ??_C@_0N@NOADMBKI@decoded?3?5?$CFs?6?$AA@
        call    ebp
    

    (sieht seeeehr nach einem reinen Funktionsaufruf aus und nicht nach der Implementation)
    Das sagt aber herzlich wenig darüber aus, was die genutzten Funktionen (z.B. std::transform()) "kosten".
    Und letztlich sagt seit Erfindung der Schleifen die Zeilenzahl deutlich weniger über die Laufzeit aus, als vorher. 😉

    Ganz davon ab: Solche Vergleiche sind relativ unsinnig, weil man oftmals Äpfel mit Birnen vergleicht. Die C++-Variante mit std::string und std::transform bietet (bzgl. Funktionalität aber auch Wartbarkeit) derartig viel mehr, dass man IMHO nicht von demselben Programm sprechen kann...

    Aber es kann gut sein, dass Dein Programm dieselbe Aufgabe in weniger Zeit ausführt als Draveres - mein Chef würde trotzdem jeden erschlagen, der für diese Aufgabenstellung Deinen Code abliefert (und nach meiner Meinung vollkommen zurecht).
    "Wäre aber schneller gewesen" ist aber schöner Grabsteinspruch. 😉

    Gruß,

    Simon2.



  • Sodale, da ja einige glauben das std::transform erste Sahne wegoptimiert wird, habe ich mal schnell einen Timer eingebaut und einen vergleich gestartet:

    //Für "Profiler"
    #include <windows.h>
    // Für C-Variante
    #include <string.h>
    #include <stdio.h>
    // Für C++-Variante
    #include <iostream>
    #include <algorithm>
    
    double get_system_time (void)
    {
        static LARGE_INTEGER Frequency;
        static BOOL UseHighPerformanceTimer = QueryPerformanceFrequency(&Frequency);
        static LARGE_INTEGER CurrentTime;
    
        if (UseHighPerformanceTimer)
        {        
            QueryPerformanceCounter(&CurrentTime);
            return static_cast<double>(CurrentTime.QuadPart) / Frequency.QuadPart;
        }
    
        return GetTickCount() * 0.001;
    }
    
    inline char rot13 (char c)
    {
        return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13);
    }
    
    int main()
    {
        get_system_time ();
    
        // durchläufe
        size_t runs = 5000000;
        // timestamps
        double start = .0;
        double end = .0;
    
        //////////////////////////////////////////////////////////////////////////
        // C Variante
        //////////////////////////////////////////////////////////////////////////
        start = get_system_time ();
        {
            char buffer[] = "hallo, caeser rocks!";
            size_t length = strlen (buffer); 
    
            for (size_t a = 0; a < runs; ++a)
            {
                // encode
                for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i); 
                // decode
                for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i); 
            }
        }
        end = get_system_time ();
        printf ("C Variante   : %.016f\n", end - start);
    
        //////////////////////////////////////////////////////////////////////////
        // C++ Variante
        //////////////////////////////////////////////////////////////////////////
        start = get_system_time ();
        {
            std::string buffer = "hallo, caeser rocks!";
    
            for (size_t a = 0; a < runs; ++a)
            {
                // encode
                std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13); 
                // decode
                std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13); 
            }
        }
        end = get_system_time ();
        printf ("C++ Variante : %.016f\n", end - start);
    
        return 0;
    }
    

    Ich habe das Programm 500x gestartet und aus den einzelnen Werten den gesamtdurchschnitt ermittelt. Bei einer Durchlaufanzahl von 5000000 kam hierbei durchschnittlich folgendes Ergebnis zustande.

    500 Aufrufe á 5000000 Durchläufe
    Durchschnitt bei der C Variante: 4.6239418697077781
    Durchschnitt bei der C++ Variante: 9.1223112155319541

    Aber ja, ist ja Halbwissen und eine Abschätzung, ja ja. 😃

    Getestet wurde dies übrigends auf einem AMD Turion64 1,6 GHz.

    edit
    Interessant ist übrigends das folgende Variante noch langsamer ist als die mit std::transform:

    //////////////////////////////////////////////////////////////////////////
        // C++ Variante 2
        //////////////////////////////////////////////////////////////////////////
        start = get_system_time ();
        {
            std::string buffer = "hallo, caeser rocks!";
            size_t length = buffer.length ();
    
            for (size_t a = 0; a < runs; ++a)
            {
                // encode
                for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i); 
                // decode
                for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i); 
            }
        }
        end = get_system_time ();
    

    Durchschnittlich 10sec. Grund hierfür ist, dass der ArrayAccess-Operator nicht geinlined wird, wodurch mehr calls, push, pops und movs als bei der std::transform-Variante entstehen. Dazu fehlt hierbei die Zeiger-Jongliererei, welche bei std::transform im Hintergrund läuft.

    Simon2[/b]
    Okay, das dich ein Chef dafür erschlagen würde kommt drauf an, ich code nur für Embedded-Systeme und da lernt man sowas eigentlich recht gut. 😉 Aber ist ja Halbwissen und Abschätzung. Nicht wahr, Dravere?



  • unsigned long schrieb:

    ...
    Simon2
    Okay, das dich ein Chef dafür erschlagen würde kommt drauf an, ich code nur für Embedded-Systeme und da lernt man sowas eigentlich recht gut. ...

    Auch wenn das für bestimmte Plattformen sinnvoll optimiert sein mag, vermute ich, dass der gute pampy hier auf der Suche nach einer "Standardlösung" war.
    Ansonsten hätte ich noch anzubieten:

    #include <cca.h>
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        return cca_rot(buff, strlen (buffer), 13);
    }
    

    ist auf unserem embedded system (CCA) garantiert noch performanter. 😉

    Und wie schongesagt: std::string macht halt einfach unglaublich viel mehr als ein char-Array... und ich könnte mir vorstellen, dass allein schon die dynamische Speicherverwaltung (kenne eine std::string-Implementierung, die nur für Zeichenketten < 16 Byte auf dem Stack handelt) einen großen Happen des Overheads übernimmt. Was sagt denn Dein Test zu std::transform() auf ein char-Array?

    Gruß,

    Simon2.



  • Okay, gegen common component hat mein Code keine Chance. 😉 Waren da nicht die bereitgestellten Funktionen auch irgendwie im Prozessor drin implementiert? Hab da irgendwie mal was darüber gelesen.

    Das ist klar, das std::string viel mehr macht als ein einfacher popeliger Speicherbereich. Aber zu sagen: "wird alles schön wegoptimiert, ist ja C++, benutzt ja jeder - wehe du sagst was dagegen, ansonsten ist das Halbwissen und Abschätzung." ist auch nicht gerade die Krone.

    Probiers mal aus was std::transform auf char-array macht. Code steht ja oben damit jeder selber testen kann. 🙂

    edit
    Das kommt bei mir raus, wenn ich std::transform auf char[] benutze.

    char buffer[] = "hallo, caeser rocks!";
            size_t length = strlen (buffer); 
    
            for (size_t a = 0; a < runs; ++a)
            {
                // encode
                std::transform(buffer, buffer + length, buffer, &rot13);  
                // decode
                std::transform(buffer, buffer + length, buffer, &rot13);
            }
    

    7.4681667642107641sec

    Kommt aber sicherlich auch auf die STL-Implementierung an. Ich habe nur die Standardimplementierung aus dem VC++2008 SP1



  • Sag mal unsigned long, verstehst du nicht was ich meinte ? Stehste so ein bisschen auf dem Schlauch ? Ich hab dein Programm 1 zu 1 in meine IDE kopiert und es ging NICHT. Dann habe ich dein Code Zitiert, musste aber in dem Beitrag das "i" durch das "j" ändern, damit ich die i Tags benutzen kann um eine Schrift wie "Test" zu benutzen. Sorry das ich darauf weiter rumhacke, aber ich lass mich nicht für dumm verkaufen und als Codefälscher dahin stellen...



  • FreakY<3Cpp schrieb:

    ...als Codefälscher dahin stellen...

    OT: Ist mir schon öfter aufgefallen (und ich bin auch nicht gefeit dagegen), dass Diskussionen sehr in die Länge gezogen und gleichzeitig verbissener als auch sinnfreier werden, weil bei einer Meinuingsverschiedenheit
    a) "Gegnerrollen" eingenommen werden (jeder zieht sich selbst in "seine Ecke" und drängt gleichzeitig den Anderen in "dessen Ecke") und
    b) gleich dem "Gegner" ehrrührige Motive (Betrug, Dummheit, ...) unterstellt werden.

    Finde es seltsam und gleichzeitig in zunehmenden Maße "unkonstruktiv". Am Ende geht es eigentlich nur noch darum, die eigene Reputation zu retten ....
    Wie gesagt: Ich tappe auch immer mal wieder in diese Falle, aber halte es für sinnvoller
    a) Seine Formulierungen (und ggf. innere Einstellungen) zu versachlichen und
    b) seinen Stolz ein wenig zu dämpfen / sein "Fell" ein wenig zu verdicken.

    Gruß,

    Simon2.


Anmelden zum Antworten