Specialised Projects > Compiler Based Assembler

Mysteries of C++ revealed

(1/4) > >>

jj2007:
After reading twice through a convoluted essay titled "C++ References" which seems to be the top Google hit for C++ by reference by pointer, I still had not the faintest idea what the guy was talking about, so I decided to look under the hood...

Enjoy ;)


--- Code: ---#include <stdio.h> //if is found in the first 1k, F5 will build all as C code

void    TheFunc(int ThePassedNumber) {
  ThePassedNumber = 0x11111111; // manipulates the stack content, i.e. [the arg]
}

void    TheFunc_ptr(int *ThePassedNumber) {
  *ThePassedNumber = 0x22222222; // gets a pointer and writes there
}

void    TheFunc_ref(int &ThePassedNumber) {
  ThePassedNumber = 0x33333333; // gets a pointer and writes there (identical to TheFuncPtr)
}

int  main(void) {
//__asm int 3; // for Olly
    int  TheNumber;
int& TheRef = TheNumber;
/*
00401079                ³?  8D45 F8             lea eax, [ebp-8]
0040107C                ³.  8945 F0             mov [ebp-10], eax  ; save a pointer to ptr TheNumber
*/
    TheNumber = 0x12345678; // writes to local memory
/*
0040107F                ³?  C745 F8 78563412    mov dword ptr [ebp-8], 12345678
*/
printf("Original number=\t%xh\n", TheNumber);

//__asm int 3;
TheFunc(TheNumber);
/*
004010A2                ³.  8B55 F8             mov edx, [ebp-8]
004010A5                ³?  52                  push edx
004010A6                ³?  E8 6EFFFFFF         call 00401019
...
TheFunc                 Ú$ À55                  push ebp      ; CppConsoleJJ.TheFunc(ThePassedNumber)
00401031                ³.  8BEC                mov ebp, esp
00401033                ³.  C745 08 11111111    mov dword ptr [ebp+8], 11111111  ; WRITE TO STACK
0040103A                ³.  5D                  pop ebp
0040103B                À.  C3                  retn
*/
    printf("My number func'ed=\t%xh (i.e. not changed)\n", TheNumber);

TheFunc_ptr(&TheNumber);
/*
004010C9                ³.  8D4D F8             lea ecx, [ebp-8]   ; ptr TheNumber
004010CC                ³?  51                  push ecx
004010CD                ³?  E8 4CFFFFFF         call 0040101E
...
TheFunc_ptr             Ú$ À55                  push ebp           ; CppConsoleJJ.TheFunc_ptr(ThePassedNumber)
00401041                ³.  8BEC                mov ebp, esp
00401043                ³.  8B45 08             mov eax, [ebp+8]
00401046                ³.  C700 22222222       mov dword ptr [eax], 22222222
0040104C                ³.  5D                  pop ebp
0040104D                À.  C3                  retn
*/
printf("My number ptr'ed=\t%xh\n", TheNumber);

TheFunc_ref(TheRef);
/*
004010F0                ³.  8B45 F0             mov eax, [ebp-10]  ; value of TheRef
004010F3                ³?  50                  push eax
004010F4                ³?  E8 2AFFFFFF         call 00401023
...
TheFunc_ref             Ú$ À55                  push ebp           ; CppConsoleJJ.TheFunc_ref(ThePassedNumber)
00401051                ³.  8BEC                mov ebp, esp
00401053                ³.  8B45 08             mov eax, [ebp+8]
00401056                ³.  C700 33333333       mov dword ptr [eax], 33333333
0040105C                ³.  5D                  pop ebp
0040105D                À.  C3                  retn
*/
printf("My real number=  \t%xh\n", TheNumber);
printf("My ref'ed number=\t%xh\n", TheRef);
return (0);
}
--- End code ---

dedndave:
looking at C++ stuff is bad for mental health   :lol:

as far as asm goes, i understand passing an address of SomeThing, rather than passing the value of SomeThing

TWell:
C++ support C, so first function is as C and second as C++

--- Code: ---...
void TheFunc_ptr(int *ThePassedNumber) {
*ThePassedNumber = 0x22222222; // gets a pointer and writes there
}
#ifdef __cplusplus
void TheFunc_ref(int &ThePassedNumber) {
ThePassedNumber = 0x33333333; // gets a pointer and writes there (identical to TheFuncPtr)
}
#endif
...
--- End code ---

jj2007:
Here is another snippet with mysterious output ;-)

#include <stdio.h>
#include <malloc.h>

int  main(void) {
   printf("%s\n\n", "References are cute!");
   int* MyArray;
   MyArray = (int*) malloc (100*sizeof(int));
   int& ElementFive = MyArray[5];
   MyArray[5]=1005;
   printf("MyArray[5]=%i, ElementFive=%i\n", MyArray[5], ElementFive);

   MyArray[5]=2*MyArray[5];
   printf("MyArray[5]=%i, ElementFive=%i\n", MyArray[5], ElementFive);

   MyArray = (int*) realloc (MyArray,100*sizeof(int));
   MyArray[5]=2*MyArray[5];
   printf("MyArray[5]=%i, ElementFive=%i\n", MyArray[5], ElementFive);

   MyArray = (int*) realloc (MyArray,1000*sizeof(int));
   MyArray[5]=2*MyArray[5];
   ElementFive=2*ElementFive;
   printf("MyArray[5]=%i, ElementFive=%i <<<<<<< great, isn't it?\n", MyArray[5], ElementFive);
   printf("%s", "\nHit Enter to end this disaster");
   getchar();
   return (0);
}

Output:
References are cute!

MyArray[5]=1005, ElementFive=1005
MyArray[5]=2010, ElementFive=2010
MyArray[5]=4020, ElementFive=4020
MyArray[5]=8040, ElementFive=-35783204 <<<<<<< great, isn't it?

Of course, seasoned assembler programmers might have an idea what happens under the hood ;)

TWell:
With msvcpp 2010 sp1
--- Code: ---References are cute!

MyArray[5]=1005, ElementFive=1005
MyArray[5]=2010, ElementFive=2010
MyArray[5]=4020, ElementFive=4020
MyArray[5]=8040, ElementFive=8040 <<<<<<< great, isn't it?

Hit Enter to end this disaster
--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version