To deepen the impression of how "(* p) ++" works, I wrote some test codes, for example:
int main() { int a = 3; int *p = &a; int b = (*p)++; int *q = p++; int c = a++; int d = c++; printf("a = %d, b = %d, c = %d, d = %d, p = %#x, q = %#x\n",a, b, c, d, p, q); }
OUTPUT IS: a = 5, b = 3, c = 5, d = 4, p = 0xc6dc3490, q = 0xc6dc348c
But my question is about assembly (codes are in order, not off):
main: push rbp mov rbp, rsp sub rsp, 48 ;int a = 3 : mov DWORD PTR [rbp-36], 3 ;int *p = &a : lea rax, [rbp-36] mov QWORD PTR [rbp-8], rax ;int b = (*p)++ : mov rax, QWORD PTR [rbp-8] mov eax, DWORD PTR [rax] lea ecx, [rax+1] ;Flag1 mov rdx, QWORD PTR [rbp-8] mov DWORD PTR [rdx], ecx mov DWORD PTR [rbp-12], eax ;int *q = p++ : mov rax, QWORD PTR [rbp-8] ;Flag2 lea rdx, [rax+4] ;Flag3 mov QWORD PTR [rbp-8], rdx mov QWORD PTR [rbp-24], rax ;int c = a++; mov eax, DWORD PTR [rbp-36] lea edx, [rax+1] ;Flag4 mov DWORD PTR [rbp-36], edx mov DWORD PTR [rbp-28], eax ;int d = c++; mov eax, DWORD PTR [rbp-28] lea edx, [rax+1] ;Flag5 mov DWORD PTR [rbp-28], edx mov DWORD PTR [rbp-32], eax ... ... (ignore some)
Please pay attention to the lines of "Flagx", which confuse me.
From above we know that
when the pointer: int * q = p ++ :
lea rdx, [rax+4] ;Flag3
Here, lea seems to read the store of addr values ββin rax and +4. then go to "rdx".
while: int c = a ++ or int d = C ++ :
lea edx, [rax+1] ;Flag4/Flag5
Here, βleaβ seems to read the contents of the addr value store in βraxβ (here 3), and +1 to 4 and goes to βedxβ.
But! the point is that rax 'in the two statutes is the same . They are all from
mov rax, QWORD PTR [rbp-8] ;Flag2
As we can see, they (Flag3 and Flag4 / Flag5) look very similar, but they work differently on the same "rax", how did it happen? Can the lea command distinguish between rdx and edx / ecx and get different results?
Thank you very much.