In modern processors it is possible to load a register from memory and then post-modify the indexing pointer by a desired value. For example, in our embedded processor, this will be done by:
ldr r0, [r1], +12
which means - load the value pointed to by r1 into r0 and then increment r1 by 12:
r0 = [r1]
r1 = r1 + 12
In the C language, using pointer arithmetics, one can assign a value using a pointer and then advance the pointer by 1:
char i, *p, a[3]={10, 20, 30};
p = &(a[0]);
i = *p++;
// now i==10 and p==&(a[1]).
I am looking for a way to dereference a pointer while post-modifying it by an offset other than 1. Is this possible in C, so it maps nicely to the similar asm instruction?
Note that:
i = *p+=2;
increases the value in a[0] w/o modifying the pointer, and:
i = *(p+=2);
pre-modifies the pointer, so in this case i==30
.
Modifying the value of a pointerWe can change the pointer's value in a code, but the downside is that the changes made also cause a change in the original variable.
You can't change the address of a pointer (or of any variable). Once you declare the variable, it's address is firmly set, once and forever. You can, however, change the value of a pointer, just as easily as you can change the value of an int: x = 10 or p = &t.
Can a pointer be changed within function? If you modify the pointer inside the called function, you only modify the copy of the pointer, but the original pointer remains unmodified and still points to the original variable.
Yes this is possible.
You shouldn't be doing weird pointer math to make it happen.
Not only is it about optimization settings, your GCC back-end needs to tell GCC that it has such a feature (i.e. when GCC itself is being compiled). Based on this knowledge, GCC automatically combines the relevant sequence into a single instruction.
i.e. if your back-end is written right, even something like:
a = *ptr;
ptr += SOME_CONST;
should become a single post-modify instruction.
How to correctly set this up when writing a back-end? (ask your friendly neighbourhood GCC back-end developer to do it for you):
If your GCC back-end is called foo
:
gcc/config/foo/
.foo.h
which contains a lot of #defines
describing machine features.HAVE_POST_INCREMENT
to evaluate to true, and if it supports post-modify, then define the macro HAVE_POST_MODIFY_DISP
to true. (post-increment => ptr++
, post-modify => ptr += CONST
). Maybe there are a few other things to be handled as well.Assuming that your processor's back-end has got this right, lets move to what happens when you compile your code containing said post-modify sequence:
There is a specific GCC optimization pass that goes through instruction pairs that fall into this category and combines them. The source for that pass is here, and has a rather clear description of what GCC will do and how to get it to do it.
But this, in the end, is not in your control as a GCC user. It is in the control of the developer who wrote your GCC back-end. All you should be doing, like the most upvoted comment says, is:
a = *ptr;
ptr += SOME_CONST;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With