從C語言到彙編(二)++/--運算

相信C語言的使用者對++/–運算符不會陌生吧。又是前綴,又是後綴的++/–一定讓你感到困惑吧!其實以前我也是這樣的,不過在學習了彙編以後,我看了C語言生成的彙編代碼,這才徹底的理解了++/–運算符。
先從最簡單的++運算符開始吧。

int main(void)
{
	int a=0;
	a++;
	++a;
	
	return 0;
}

彙編代碼

.text
.global main

main:
	pushl %ebp
	movl %esp,%ebp
	
	subl $4,%esp
	movl $0,-4(%esp);a=0
	addl $1,-4(%esp);a++
	addl $1,-4(%esp);++a
	
	movl $0,%eax
	leave
	ret

a++等於addl $1,-4(%esp)
++a等於addl $1,-4(%esp)

複雜點的。

int main(void)
{
	int a=0;
	int b=3;
	
	a=b++;
	a=++b;
	
	return 0;
}

彙編代碼

.text
.global main

main:
	pushl %ebp
	movl %esp,%ebp
	
	subl $8,%esp
	movl $0,-4(%ebp);a
	movl $3,-8(%ebp);b	
	//a=b++
	movl -8(%ebp),%eax
	addl $1,-8(%ebp)
	movl %eax,-4(%ebp)
	//a=++b
	addl $1,-8(%ebp)	
	movl -8(%ebp),%eax
	movl %eax,-4(%ebp)
	
	movl $0,%eax
	leave
	ret

a=b++先將b的值放入%eax中,再b=b+1,再將%eax的值放入a中。
a=++b先b=b+1,在將b賦值給a。

如果是放入printf函數的參數中呢?

int main(void)
{
	int a=0;
	
	printf("%d %d\n",a++,1);
	printf("%d %d\n",++a,1);
	
	return 0;
}

彙編代碼

.section .rodata
	.LC0:.string "%d %d\n"
.text
.global main

main:
	pushl %ebp
	movl %esp,%ebp
	
	subl $4,%esp
	movl $0,-4(%ebp)
	pushl $1
	pushl -4(%ebp)
	addl $1,-4(%ebp)
	pushl $.LC0
	call printf
	addl $12,%esp
	
	pushl $1
	addl $1,-4(%ebp)
	pushl -4(%ebp)
	pushl $.LC0
	call printf
	addl $12,%esp
	
	movl $0,%eax
	leave
	ret

棧裏先存放立即數1,再存放a,再a=a+1,再存放.LC0的地址,調用printf。
棧裏先存放立即數1,再a=a+1,再存放a,再存放.LC0的地址,調用printf。

困難級別的。

int main(void)
{
	int a=0;
	int b=1;
	
	a=b+++b+2;
	a=++b+b+2;
	
	return 0;
}

彙編代碼

.text
.global main

main:
	pushl %ebp
	movl %esp,%ebp
	
	subl $8,%esp
	movl $0,-4(%ebp)
	movl $1,-8(%ebp)
	movl -8(%ebp),%eax
	addl $1,-8(%ebp)
	addl %eax.%eax
	addl $2,%eax
	movl %eax,-4(%ebp)
	
	addl $1,-8(%ebp)
	movl -8(%ebp),%eax
	addl -8(%ebp),%eax
	addl $2,%eax
	movl %eax,-4(%ebp)	

	movl $0,%eax
	leave
	ret

a=b+++b+2 movl -8(%ebp),%eax 先將b的值放入%eax中,然後%eax代表b,addl $1,-8(%ebp) b=b+1
addl %eax.%eax %eax+%eax,addl $2,%eax %eax+%eax+2得到結果放入a中、
a=++b+b+2 addl $1,-8(%ebp) b=b+1 a=b+b+1。

–運算符等同於++運算符。
由於++/–過於複雜,所以我建議在一般情況下不使用++/–,只在++/–是一條語句的時候使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章