C behaves differently since it places values on the stack.
Um. Actually, C doesn't place anything on the stack. It loads the values into registers.
This is the MS compiler:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00 +.21022.08 include listing.inc INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG2413 DB 'T1', 0aH, 00H $SG2415 DB 'T2', 0aH, 00H _DATA ENDS PUBLIC main EXTRN printf:PROC pdata SEGMENT $pdata$main DD imagerel $LN5 DD imagerel $LN5+87 DD imagerel $unwind$main pdata ENDS xdata SEGMENT $unwind$main DD 010401H DD 06204H ; Function compile flags: /Odtp ; File c:\test\c\junk.c xdata ENDS _TEXT SEGMENT a$ = 32 main PROC ; 3 : void main( void ) { $LN5: sub rsp, 56 ; 00000038H ; 4 : int a = 10; mov DWORD PTR a$[rsp], 10 ; 5 : if( a == a-- ) printf( "T1\n" ); mov edx, DWORD PTR a$[rsp] mov ecx, DWORD PTR a$[rsp] mov eax, DWORD PTR a$[rsp] sub eax, 1 mov DWORD PTR a$[rsp], eax cmp edx, ecx jne SHORT $LN2@main lea rcx, OFFSET FLAT:$SG2413 call printf $LN2@main: ; 6 : if( a == --a ) printf( "T2\n" ); mov eax, DWORD PTR a$[rsp] sub eax, 1 mov DWORD PTR a$[rsp], eax mov eax, DWORD PTR a$[rsp] cmp DWORD PTR a$[rsp], eax jne SHORT $LN1@main lea rcx, OFFSET FLAT:$SG2415 call printf $LN1@main: ; 7 : } xor eax, eax add rsp, 56 ; 00000038H ret 0 main ENDP _TEXT ENDS END
The interesting thing about that is that for the post decrement, it loads the value of a into two registers (edx & ecx), then loads it a third time in to eax, where it decrements it and then writes it back. Only then does it compare hte first two values and branch accordingly.
And for the predecrement, it loads one register, decrements it and then saves it back before loading the modified value back into the same register and the comparing it with the stored value and branching accordingly.
That's before the optimiser takes a look. After the optimiser, all those shenanigins are optimised away and all that remains is the printfs:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00 +.21022.08 include listing.inc INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG2478 DB 'T1', 0aH, 00H $SG2480 DB 'T2', 0aH, 00H _DATA ENDS PUBLIC main EXTRN printf:PROC pdata SEGMENT $pdata$main DD imagerel $LN5 DD imagerel $LN5+35 DD imagerel $unwind$main pdata ENDS xdata SEGMENT $unwind$main DD 010401H DD 04204H ; Function compile flags: /Ogtpy ; File c:\test\c\junk.c xdata ENDS _TEXT SEGMENT main PROC ; 3 : void main( void ) { $LN5: sub rsp, 40 ; 00000028H ; 4 : int a = 10; ; 5 : if( a == a-- ) printf( "T1\n" ); lea rcx, OFFSET FLAT:$SG2478 call printf ; 6 : if( a == --a ) printf( "T2\n" ); lea rcx, OFFSET FLAT:$SG2480 call printf ; 7 : } xor eax, eax add rsp, 40 ; 00000028H ret 0 main ENDP _TEXT ENDS END
In reply to Re^2: Help me to understand increment / decrement operator behavior in perl
by BrowserUk
in thread Help me to understand increment / decrement operator behavior in perl
by sam_bakki
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |