L
Lew Pitcher
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
OK, here's what this piece of code does.
First off, remember that C fuction arguments are passed by value. This
piece of code makes some assumptions about the structure of the memory
around the value passed into the change() function, and it's
relationship to code in the main() function.
i is a pointer to int, and on this platform, consumes a place in a
structure called a stack.
This statement sets the value of the storage pointed to by i to 23.
This is equivalent to the effects of a statement "i = 23;" in main()
First off, this can only legally be done in C99. Previous versions of
the C standard would call this a syntax error, as declarations cannot
follow statements, and there has already been one statement.
This defines ptr to be a pointer to characters, which points to the
location of the /argument/ on the "stack". We now know where the value
is stored for the "pass by value" argument to change()
This decrements the pointer by the size of 1 integer. On a specific
platform, this "backs up" the pointer so that it now points to an
architectural artifact of this compiler/platform. Under certain
circumstances, the artifact that ptr now points to is the 'return
address' in main() to where a "return;" statement in change() will go
to.
First off, this can only legally be done in C99. Previous versions of
the C standard would call this a syntax error, as declarations cannot
follow statements, and there has already been one statement.
This defines int_ptr which is a pointer to int, and points to the same
location that ptr points to. Presumably this is still the 'return
address'
This increments the 'return address' by 10 chars. Presumably, this
will change the 'return address' such that the termination of change()
will now skip the machine instructions in main() that implement the
"i=6;" statement
And back we go to main(), presumably to a point 10 chars past where
the compiler intended us to go. If all the factors are correct, we've
just implicitly jumped past the "i=6;" statement in main(), and the
value of i set by change() will not have been changed.
That's because this is a non-portable, compiler-dependant,
platform-dependant, processor-dependant solution, and you don't have the
same compiler/platform/processor combination as the OP.
The OPs solution depends on
- - arguments being passed in a "stack" structure
- - a specific arrangement of hidden architectural elements on the stack
(i.e. the return address being stored immediately adjacent to the
arguments)
- - a specific size for one of the hidden architectural elements
- - a specific number of machine instruction bytes being generated
for a specific C statement
- - no compiler tricks like branch optimization, storage optimization, or
other internal arrangements that could intervene dynamically in the
code path that he is trying to skip
In other words, a completely platform-specific implementation.
- --
Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group
(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
iD8DBQFDGFxWagVFX4UWr64RAhp/AJ9T1+iG0OuKSKmMprLpy2jD5W3tGgCfe/zS
dbFwMaz6+GRo0hRQT3Vgj4s=
=njdq
-----END PGP SIGNATURE-----
Hash: SHA1
Marc said:What are you trying to do there ? Could you give me
some explanation ? Something like:
void change(int* i){
*i= 23;
char* ptr= (char*) &i;
ptr-= sizeof(int);
int* int_ptr= (int*) ptr;
*ptr+= 10;
}
OK, here's what this piece of code does.
First off, remember that C fuction arguments are passed by value. This
piece of code makes some assumptions about the structure of the memory
around the value passed into the change() function, and it's
relationship to code in the main() function.
void change(int* i){
i is a pointer to int, and on this platform, consumes a place in a
structure called a stack.
*i= 23;
This statement sets the value of the storage pointed to by i to 23.
This is equivalent to the effects of a statement "i = 23;" in main()
char* ptr= (char*) &i;
First off, this can only legally be done in C99. Previous versions of
the C standard would call this a syntax error, as declarations cannot
follow statements, and there has already been one statement.
This defines ptr to be a pointer to characters, which points to the
location of the /argument/ on the "stack". We now know where the value
is stored for the "pass by value" argument to change()
ptr-= sizeof(int);
This decrements the pointer by the size of 1 integer. On a specific
platform, this "backs up" the pointer so that it now points to an
architectural artifact of this compiler/platform. Under certain
circumstances, the artifact that ptr now points to is the 'return
address' in main() to where a "return;" statement in change() will go
to.
int* int_ptr= (int*) ptr;
First off, this can only legally be done in C99. Previous versions of
the C standard would call this a syntax error, as declarations cannot
follow statements, and there has already been one statement.
This defines int_ptr which is a pointer to int, and points to the same
location that ptr points to. Presumably this is still the 'return
address'
*ptr+= 10;
This increments the 'return address' by 10 chars. Presumably, this
will change the 'return address' such that the termination of change()
will now skip the machine instructions in main() that implement the
"i=6;" statement
And back we go to main(), presumably to a point 10 chars past where
the compiler intended us to go. If all the factors are correct, we've
just implicitly jumped past the "i=6;" statement in main(), and the
value of i set by change() will not have been changed.
By the way, on my linux/x86/gcc, the output is 134513642, not
23...
That's because this is a non-portable, compiler-dependant,
platform-dependant, processor-dependant solution, and you don't have the
same compiler/platform/processor combination as the OP.
The OPs solution depends on
- - arguments being passed in a "stack" structure
- - a specific arrangement of hidden architectural elements on the stack
(i.e. the return address being stored immediately adjacent to the
arguments)
- - a specific size for one of the hidden architectural elements
- - a specific number of machine instruction bytes being generated
for a specific C statement
- - no compiler tricks like branch optimization, storage optimization, or
other internal arrangements that could intervene dynamically in the
code path that he is trying to skip
In other words, a completely platform-specific implementation.
Marc Boyer
- --
Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group
(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
iD8DBQFDGFxWagVFX4UWr64RAhp/AJ9T1+iG0OuKSKmMprLpy2jD5W3tGgCfe/zS
dbFwMaz6+GRo0hRQT3Vgj4s=
=njdq
-----END PGP SIGNATURE-----