文中均設i=5,彙編代碼:movl $5, -4(%rbp) // 將5賦值給rdp向下偏移4個指針的頭指針(i)
在裝用gcc環境的PC下,能夠使用gcc -S -o assembly.S yourcodefile.c
打印彙編代碼。首先打印出簡單自增運算的彙編代碼:函數
在早版本的編譯器中多是以下表達形式,而在最新版的gcc中,i++;
與++i;
的彙編代碼是同樣的。指針
movl -4(%rbp), %eax // 將i賦值給ax寄存器, ax=5 leal 1(%rax), %edx // 將ax寄存器的值加1賦值給dx寄存器, dx=ax+1=6 movl %edx, -4(%rbp) // 將dx寄存器的值賦值給i, i=dx=6
addl $1, -4(%rbp) // 將i的值增長1賦值給i, i=6
經過拓展i++;
的早期彙編代碼,能夠推出printf("$d",i++);
的彙編代碼以下所示:code
movl -4(%rbp), %eax // 將i賦值給ax寄存器, ax=5 leal 1(%rax), %edx // 將ax寄存器的值加1賦值給dx寄存器, dx=ax+1=6 movl %edx, -4(%rbp) // 將dx寄存器的值賦值給i, i=dx=6 movl %eax, %edx // 將ax寄存器的值賦值給dx寄存器, dx=ax=5 call _printf // 調用printf函數,打印dx寄存器的值5
不難發現,在進行自增運算操做以前,i的原始值5已經被提早存入寄存器ax中,進行完自增操做後,從ax寄存器中取出i的原始值編譯器
經過拓展++i;
的彙編代碼,能夠推出printf("$d",++i);
以下所示:asm
addl $1, -4(%rbp) // 將i的值增長1賦值給i, i=6 movl -4(%rbp), %eax // 將i賦值給ax寄存器, ax=6 movl %eax, %edx // 將ax寄存器的值賦值給dx寄存器, dx=ax=6 call _printf // 調用printf函數,打印dx寄存器的值6
與printf("$d",i++);
相比,主要是movl -4(%rbp), %eax
所在的位置不一致,這是由自己的性質決定的編譯
結合i++;
與++i;
的彙編代碼,能夠推出printf("%d%d",i++,++i)
的彙編代碼以下所示:class
/*++i part1 begin*/ addl $1, -4(%rbp) // 將i的值增長1賦值給i, i=6 /*++i part1 end*/ /*i++ begin*/ movl -4(%rbp), %eax // 將i賦值給ax寄存器, ax=6 leal 1(%rax), %edx // 將ax寄存器的值加1賦值給dx寄存器, dx=ax+1=7 movl %edx, -4(%rbp) // 將dx寄存器的值賦值給i, i=dx=7 /*i++ end*/ /*++i part2 begin*/ movl -4(%rbp), %edx // 將i賦值給dx寄存器, ax=7 /*++i part2 end*/ movl %edx, %ecx // 把7賦值給cx寄存器 movl %eax, %edx // 把6賦值給dx寄存器 call _printf // 調用printf函數,打印dx、cx寄存器
可見printf("%d %d",i++,++i)
的輸出是6 7
gcc
結合i++;
與++i;
的彙編代碼,能夠推出printf("%d%d",i++,++i)
的彙編代碼以下所示:file
/*2nd i++ begin*/ movl -4(%rbp), %edx // 將i賦值給ax寄存器, dx=5 leal 1(%rdx), %eax // 將dx寄存器的值加1賦值給ax寄存器, ax=dx+1=6 movl %eax, -4(%rbp) // 將ax寄存器的值賦值給i, i=ax=6 /*2nd i++ end*/ /*1st i++ begin*/ movl -4(%rbp), %eax // 將i賦值給ax寄存器, ax=i=6 leal 1(%rax), %ecx // 將ax寄存器的值加1賦值給cx寄存器, cx=ax+1=7 movl %ecx, -4(%rbp) // 將cx寄存器的值賦值給i, i=cx=7 /*1st i++ end*/ movl %edx, %ecx // 把5賦值給cx寄存器 movl %eax, %edx // 把6賦值給dx寄存器 call _printf // 調用printf函數,打印dx、cx寄存器
可見printf("%d %d",i++,++i)
的輸出是6 5
gc
結合i++;
與++i;
的彙編代碼,能夠推出printf("%d %d",i++,++i,i++)
的彙編代碼以下所示:
/*2nd i++ begin*/ movl -4(%rbp), %edx // 將i賦值給ax寄存器, dx=5 leal 1(%rdx), %eax // 將dx寄存器的值加1賦值給ax寄存器, ax=dx+1=6 movl %eax, -4(%rbp) // 將ax寄存器的值賦值給i, i=ax=6 /*2nd i++ end*/ /*++i part1 begin*/ addl $1, -4(%rbp) // 將i的值增長1賦值給i, i=7 /*++i part1 end*/ /*1st i++ begin*/ movl -4(%rbp), %eax // 將i賦值給ax寄存器, ax=i=7 leal 1(%rax), %ecx // 將ax寄存器的值加1賦值給cx寄存器, cx=ax+1=8 movl %ecx, -4(%rbp) // 將cx寄存器的值賦值給i, i=cx=8 /*1st i++ end*/ /*++i part2 begin*/ movl -4(%rbp), %ecx // 將i賦值給cx寄存器, cx=8 /*++i part2 end*/ movl %edx, %n // 把5賦值給n寄存器 movl %ecx, %n2 // 把8賦值給n2寄存器 movl %eax, %edx // 把7賦值給dx寄存器 call _printf // 調用printf函數,打印dx、n二、n寄存器
可見printf("%d %d %d",i++,++i,i++)
的輸出是7 8 5
,那麼printf("%d %d",++i,++i)
的輸出是7 7
,printf("%d %d",++i,i++)
的輸出是7 5