从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。

–运算符等同于++运算符。
由于++/–过于复杂,所以我建议在一般情况下不使用++/–,只在++/–是一条语句的时候使用

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