C语言基础:形参与实参

上课老师会给你讲函数的形参与实参的概念,前期基本上背诵,没有真正理解。这里写一个简单的例子说明下。

测试用例如下:
在这里插入图片描述
arm-linux-gcc test_para.c -o test_para 这里用交叉编译工具,方便后面读汇编代码

测试结果,很明显real_swap_func才能达到交换的目的
在这里插入图片描述
简单的说你得往变量的地址写数据才能生效。形参只是往栈空间的某个地址写了一个数据,这个数据的值和入参的值相同,但是这个地址却不是形参本身的地址。

先反汇编得到汇编代码:
arm-linux-objdump -S test_para > test_para.txt
读汇编再来深入理解:

00008490 <fake_swap_func>:
8490: e1a0c00d mov ip, sp
8494: e92dd800 stmdb sp!, {fp, ip, lr, pc}
8498: e24cb004 sub fp, ip, #4 ; 0x4
849c: e24dd00c sub sp, sp, #12 ; 0xc
84a0: e50b0010 str r0, [fp, #-16]
84a4: e50b1014 str r1, [fp, #-20]
84a8: e51b3010 ldr r3, [fp, #-16]
84ac: e50b3018 str r3, [fp, #-24]
84b0: e51b3014 ldr r3, [fp, #-20]
84b4: e50b3010 str r3, [fp, #-16]
84b8: e51b3018 ldr r3, [fp, #-24]
84bc: e50b3014 str r3, [fp, #-20]
84c0: e24bd00c sub sp, fp, #12 ; 0xc
84c4: e89da800 ldmia sp, {fp, sp, pc}

000084c8 <real_swap_func>:
84c8: e1a0c00d mov ip, sp
84cc: e92dd800 stmdb sp!, {fp, ip, lr, pc}
84d0: e24cb004 sub fp, ip, #4 ; 0x4
84d4: e24dd00c sub sp, sp, #12 ; 0xc
84d8: e50b0010 str r0, [fp, #-16]
84dc: e50b1014 str r1, [fp, #-20]
84e0: e51b3010 ldr r3, [fp, #-16]
84e4: e5933000 ldr r3, [r3]
84e8: e50b3018 str r3, [fp, #-24]
84ec: e51b2010 ldr r2, [fp, #-16]
84f0: e51b3014 ldr r3, [fp, #-20]
84f4: e5933000 ldr r3, [r3]
84f8: e5823000 str r3, [r2]
84fc: e51b2014 ldr r2, [fp, #-20]
8500: e51b3018 ldr r3, [fp, #-24]
8504: e5823000 str r3, [r2]
8508: e24bd00c sub sp, fp, #12 ; 0xc
850c: e89da800 ldmia sp, {fp, sp, pc}

00008510 :
8510: e1a0c00d mov ip, sp
8514: e92dd800 stmdb sp!, {fp, ip, lr, pc}
8518: e24cb004 sub fp, ip, #4 ; 0x4
851c: e24dd008 sub sp, sp, #8 ; 0x8
8520: e3a03003 mov r3, #3 ; 0x3 //往r3寄存器写0x3,也就是变量a的值
8524: e50b3010 str r3, [fp, #-16] //把r3的值写入fp-16的栈地址上
8528: e3a03005 mov r3, #5 ; 0x5 //往r3寄存器写0x5,也就是变量b的值
852c: e50b3014 str r3, [fp, #-20] //把r3的值写入fp-20的栈地址上
8530: e51b0010 ldr r0, [fp, #-16] //从fp-16的栈地址的值往r0寄存器写0x3,变量a的值
8534: e51b1014 ldr r1, [fp, #-20] //从fp-20的栈地址的值往r1寄存器写0x5,变量b的值
8538: ebffffd4 bl 8490 <fake_swap_func> //调用函数fake_swap_func,传参数r0, r1 ,了解arm传参机制
853c: e59f003c ldr r0, [pc, #60] ; 8580 <.text+0x1e4>
8540: e51b1010 ldr r1, [fp, #-16]
8544: e51b2014 ldr r2, [fp, #-20]
8548: ebffff90 bl 8390 <.text-0xc>
854c: e24b3010 sub r3, fp, #16 ; 0x10 //把fp-16的值(变量a的地址)写入r3寄存器,这里很重要
8550: e24b2014 sub r2, fp, #20 ; 0x14 //把fp-20的值(变量b的地址)写入r2寄存器,这里很重要
8554: e1a00003 mov r0, r3 //寄存器r3的值写入r0,这时候r0存的是变量a的地址
8558: e1a01002 mov r1, r2 //寄存器r2的值写入r1,这时候r1存的是变量 b的地址
855c: ebffffd9 bl 84c8 <real_swap_func> //调用函数fake_swap_func,传参数r0, r1
8560: e59f0018 ldr r0, [pc, #24] ; 8580 <.text+0x1e4>
8564: e51b1010 ldr r1, [fp, #-16]
8568: e51b2014 ldr r2, [fp, #-20]
856c: ebffff87 bl 8390 <.text-0xc>
8570: e3a03000 mov r3, #0 ; 0x0
8574: e1a00003 mov r0, r3
8578: e24bd00c sub sp, fp, #12 ; 0xc
857c: e89da800 ldmia sp, {fp, sp, pc}
8580: 00008698 muleq r0, r8, r6

ps:8510 是main函数的地址,不知道为何不能显示

末尾再写句废话:真正想了解C语言,汇编是无法逃避的

猜你喜欢

转载自blog.csdn.net/xp5120606a/article/details/107130622