看《深入理解计算机系统》觉得深入理解了函数之间的参数传递,但是今天一写代码就出错了。
函数对接收进来的参数都会在自己的运行时间和空间内(栈段和寄存器)有一个拷贝,所有都是,指针也是,只不过指针指向地址还是那个。
代码一,参数为普通变量
void foo(int a)
{
a= 1;
}
int main()
{
int x = 6;
foo(x);
}
对应的汇编代码的一部分如下:
080483ed <foo>:
80483ed: 55 push %ebp
80483ee: 89 e5 mov %esp,%ebp
80483f0: 83 ec 10 sub $0x10,%esp
80483f3: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
80483fa: c9 leave
80483fb: c3 ret
080483fc <main>:
80483fc: 55 push %ebp
80483fd: 89 e5 mov %esp,%ebp
80483ff: 83 ec 14 sub $0x14,%esp
8048402: c7 45 fc 06 00 00 00 movl $0x6,-0x4(%ebp)
8048409: 8b 45 fc mov -0x4(%ebp),%eax
804840c: 89 04 24 mov %eax,(%esp)
804840f: e8 d9 ff ff ff call 80483ed <foo>
8048414: c9 leave
8048415: c3 ret
8048416: 66 90 xchg %ax,%ax
8048418: 66 90 xchg %ax,%ax
804841a: 66 90 xchg %ax,%ax
804841c: 66 90 xchg %ax,%ax
804841e: 66 90 xchg %ax,%ax
可以看到foo函数只是将数1放在了自己的栈段,并不会影响main函数栈段内的数据。
代码2, 参数为指针
void foo(int *a)
{
*a= 1;
}
int main()
{
int *x, y = 6;
x = &y;
foo(x);
}
对应汇编:
080483ed <foo>:
80483ed: 55 push %ebp
80483ee: 89 e5 mov %esp,%ebp
80483f0: 8b 45 08 mov 0x8(%ebp),%eax
80483f3: c7 00 01 00 00 00 movl $0x1,(%eax)
80483f9: 5d pop %ebp
80483fa: c3 ret
080483fb <main>:
80483fb: 55 push %ebp
80483fc: 89 e5 mov %esp,%ebp
80483fe: 83 ec 14 sub $0x14,%esp
8048401: c7 45 f8 06 00 00 00 movl $0x6,-0x8(%ebp)
8048408: 8d 45 f8 lea -0x8(%ebp),%eax
804840b: 89 45 fc mov %eax,-0x4(%ebp)
804840e: 8b 45 fc mov -0x4(%ebp),%eax
8048411: 89 04 24 mov %eax,(%esp)
8048414: e8 d4 ff ff ff call 80483ed <foo>
8048419: c9 leave
804841a: c3 ret
804841b: 66 90 xchg %ax,%ax
804841d: 66 90 xchg %ax,%ax
804841f: 90 nop
可以看到在main函数里面是将y=8的地址放在%eax里面,又将%eax的值放在mian函数自己的栈段里面,在foo函数里面将传递进来的指针参数放在了寄存器%eax里面,然后让%eax指向的地址值变为1。
新开公众号“码家村”,欢迎关注