printf中的自增運算符

前言

文中均設i=5,彙編代碼:movl $5, -4(%rbp) // 將5賦值給rdp向下偏移4個指針的頭指針(i)
在裝用gcc環境的PC下,能夠使用gcc -S -o assembly.S yourcodefile.c 打印彙編代碼。首先打印出簡單自增運算的彙編代碼:函數

i++; 的彙編代碼

在早版本的編譯器中多是以下表達形式,而在最新版的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

++i; 的彙編代碼

addl $1, -4(%rbp)    // 將i的值增長1賦值給i, i=6

printf函數的自增運算符

printf("%d",i++);

經過拓展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的原始值編譯器

printf("%d",++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所在的位置不一致,這是由自己的性質決定的編譯

printf("%d %d",i++,++i)

結合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 7gcc

printf("%d %d",i++,i++)

結合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 5gc

printf("%d %d %d",i++,++i,i++)

結合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 7printf("%d %d",++i,i++)的輸出是7 5

相關文章
相關標籤/搜索