C语言结构体传参分析
来源:互联网 发布:mac能打dota2吗 编辑:程序博客网 时间:2024/06/03 13:32
从来没有直接使用结构体传参,想了解一下编译器是如何处理的,写了个简单的C文件编译后分析一下。
test.c文件:
#include <stdio.h>struct ttt{ unsigned long w; unsigned long h;};unsigned long test_ttt(struct ttt test){ return test.w + test.h;}int main(void){ struct ttt test; test.w = 10; test.h = 20; test_ttt(test); return 0;}
使用下面的命令生成test.S汇编文件
arm-none-linux-gnueabi-gcc -g3 test.c
arm-none-linux-gnueabi-objdump -Slz a.out > test.S
a.out: file format elf32-littlearmDisassembly of section .init:0000830c <_init>:_init(): 830c:e92d4008 push{r3, lr} 8310:eb00001e bl8390 <call_gmon_start> 8314:e8bd4008 pop{r3, lr} 8318:e12fff1e bxlrDisassembly of section .plt:0000831c <.plt>: 831c:e52de004 push{lr}; (str lr, [sp, #-4]!) 8320:e59fe004 ldrlr, [pc, #4]; 832c <_init+0x20> 8324:e08fe00e addlr, pc, lr 8328:e5bef008 ldrpc, [lr, #8]! 832c:0000837c .word0x0000837c 8330:e28fc600 addip, pc, #0, 12 8334:e28cca08 addip, ip, #8, 20; 0x8000 8338:e5bcf37c ldrpc, [ip, #892]!; 0x37c 833c:e28fc600 addip, pc, #0, 12 8340:e28cca08 addip, ip, #8, 20; 0x8000 8344:e5bcf374 ldrpc, [ip, #884]!; 0x374 8348:e28fc600 addip, pc, #0, 12 834c:e28cca08 addip, ip, #8, 20; 0x8000 8350:e5bcf36c ldrpc, [ip, #876]!; 0x36cDisassembly of section .text:00008354 <_start>:_start(): 8354:e3a0b000 movfp, #0 8358:e3a0e000 movlr, #0 835c:e49d1004 pop{r1}; (ldr r1, [sp], #4) 8360:e1a0200d movr2, sp 8364:e52d2004 push{r2}; (str r2, [sp, #-4]!) 8368:e52d0004 push{r0}; (str r0, [sp, #-4]!) 836c:e59fc010 ldrip, [pc, #16]; 8384 <_start+0x30> 8370:e52dc004 push{ip}; (str ip, [sp, #-4]!) 8374:e59f000c ldrr0, [pc, #12]; 8388 <_start+0x34> 8378:e59f300c ldrr3, [pc, #12]; 838c <_start+0x38> 837c:ebffffee bl833c <_init+0x30> 8380:ebffffea bl8330 <_init+0x24> 8384:00008554 .word0x00008554 8388:0000843c .word0x0000843c 838c:00008478 .word0x0000847800008390 <call_gmon_start>:call_gmon_start(): 8390:e92d4008 push{r3, lr} 8394:e59f3018 ldrr3, [pc, #24]; 83b4 <call_gmon_start+0x24> 8398:e59f0018 ldrr0, [pc, #24]; 83b8 <call_gmon_start+0x28> 839c:e08f3003 addr3, pc, r3 83a0:e7932000 ldrr2, [r3, r0] 83a4:e3520000 cmpr2, #0 83a8:1bffffe6 blne8348 <_init+0x3c> 83ac:e8bd4008 pop{r3, lr} 83b0:e12fff1e bxlr 83b4:00008304 .word0x00008304 83b8:00000018 .word0x00000018000083bc <__do_global_dtors_aux>:__do_global_dtors_aux(): 83bc:e59f3010 ldrr3, [pc, #16]; 83d4 <__do_global_dtors_aux+0x18> 83c0:e5d32000 ldrbr2, [r3] 83c4:e3520000 cmpr2, #0 83c8:03a02001 moveqr2, #1 83cc:05c32000 strbeqr2, [r3] 83d0:e12fff1e bxlr 83d4:000106cc .word0x000106cc000083d8 <frame_dummy>:frame_dummy(): 83d8:e59f0024 ldrr0, [pc, #36]; 8404 <frame_dummy+0x2c> 83dc:e92d4008 push{r3, lr} 83e0:e5903000 ldrr3, [r0] 83e4:e3530000 cmpr3, #0 83e8:0a000003 beq83fc <frame_dummy+0x24> 83ec:e59f3014 ldrr3, [pc, #20]; 8408 <frame_dummy+0x30> 83f0:e3530000 cmpr3, #0 83f4:11a0e00f movnelr, pc 83f8:112fff13 bxner3 83fc:e8bd4008 pop{r3, lr} 8400:e12fff1e bxlr 8404:000105b4 .word0x000105b4 8408:00000000 .word0x000000000000840c <test_ttt>:test_ttt():/home/user/test.c:9unsigned long w;unsigned long h;};unsigned long test_ttt(struct ttt test){ 840c:e52db004 push{fp}; (str fp, [sp, #-4]!) 8410:e28db000 addfp, sp, #0 8414:e24dd00c subsp, sp, #12 8418:e24b300c subr3, fp, #12 841c:e8830003 stmr3, {r0, r1}/home/user/test.c:10return test.w + test.h; 8420:e51b200c ldrr2, [fp, #-12] 8424:e51b3008 ldrr3, [fp, #-8] 8428:e0823003 addr3, r2, r3/home/user/test.c:11} 842c:e1a00003 movr0, r3 8430:e28bd000 addsp, fp, #0 8434:e49db004 pop{fp}; (ldr fp, [sp], #4) 8438:e12fff1e bxlr0000843c <main>:main():/home/user/test.c:13int main(void){ 843c:e92d4800 push{fp, lr} 8440:e28db004 addfp, sp, #4 8444:e24dd008 subsp, sp, #8/home/user/test.c:16struct ttt test;test.w = 10; 8448:e3a0300a movr3, #10 844c:e50b300c strr3, [fp, #-12]/home/user/test.c:17test.h = 20; 8450:e3a03014 movr3, #20 8454:e50b3008 strr3, [fp, #-8]/home/user/test.c:19test_ttt(test); 8458:e24b300c subr3, fp, #12 845c:e8930003 ldmr3, {r0, r1} 8460:ebffffe9 bl840c <test_ttt>/home/user/test.c:21return 0; 8464:e3a03000 movr3, #0/home/user/test.c:22} 8468:e1a00003 movr0, r3 846c:e24bd004 subsp, fp, #4 8470:e8bd4800 pop{fp, lr} 8474:e12fff1e bxlr00008478 <__libc_csu_init>:__libc_csu_init(): 8478:e92d47f0 push{r4, r5, r6, r7, r8, r9, sl, lr} 847c:e1a0a000 movsl, r0 8480:e1a08001 movr8, r1 8484:e1a07002 movr7, r2 8488:e59f40bc ldrr4, [pc, #188]; 854c <__libc_csu_init+0xd4> 848c:ebffff9e bl830c <_init> 8490:e59f10b8 ldrr1, [pc, #184]; 8550 <__libc_csu_init+0xd8> 8494:e08f4004 addr4, pc, r4 8498:e08f0001 addr0, pc, r1 849c:e0649000 rsbr9, r4, r0 84a0:e1b09149 asrsr9, r9, #2 84a4:0a000026 beq8544 <__libc_csu_init+0xcc> 84a8:e3a06001 movr6, #1 84ac:e4943004 ldrr3, [r4], #4 84b0:e1a0000a movr0, sl 84b4:e1a01008 movr1, r8 84b8:e1a02007 movr2, r7 84bc:e2495001 subr5, r9, #1 84c0:e1a0e00f movlr, pc 84c4:e12fff13 bxr3 84c8:e1560009 cmpr6, r9 84cc:e0055006 andr5, r5, r6 84d0:0a00001b beq8544 <__libc_csu_init+0xcc> 84d4:e3550000 cmpr5, #0 84d8:0a000008 beq8500 <__libc_csu_init+0x88> 84dc:e494c004 ldrip, [r4], #4 84e0:e1a0000a movr0, sl 84e4:e1a01008 movr1, r8 84e8:e1a02007 movr2, r7 84ec:e3a06002 movr6, #2 84f0:e1a0e00f movlr, pc 84f4:e12fff1c bxip 84f8:e1560009 cmpr6, r9 84fc:0a000010 beq8544 <__libc_csu_init+0xcc> 8500:e1a05004 movr5, r4 8504:e4953004 ldrr3, [r5], #4 8508:e1a0000a movr0, sl 850c:e1a01008 movr1, r8 8510:e1a02007 movr2, r7 8514:e1a0e00f movlr, pc 8518:e12fff13 bxr3 851c:e2866002 addr6, r6, #2 8520:e594c004 ldrip, [r4, #4] 8524:e1a0000a movr0, sl 8528:e1a01008 movr1, r8 852c:e1a02007 movr2, r7 8530:e1a0e00f movlr, pc 8534:e12fff1c bxip 8538:e1560009 cmpr6, r9 853c:e2854004 addr4, r5, #4 8540:1affffee bne8500 <__libc_csu_init+0x88> 8544:e8bd47f0 pop{r4, r5, r6, r7, r8, r9, sl, lr} 8548:e12fff1e bxlr 854c:00008110 .word0x00008110 8550:00008110 .word0x0000811000008554 <__libc_csu_fini>:__libc_csu_fini(): 8554:e12fff1e bxlrDisassembly of section .fini:00008558 <_fini>:_fini(): 8558:e92d4008 push{r3, lr} 855c:e8bd4008 pop{r3, lr} 8560:e12fff1e bxlr
结论: 结构体传参是通过栈实现的,而结构体指针传参是使用寄存器。我们知道,寄存器的读写速度远远高于SDRAM读写速度,所以,尽可能使用结构体指针传参代替结构体传参。
- C语言结构体传参分析
- C语言结构分析
- C语言选择结构与循环结构逆向分析
- C语言基础:C语言结构体(2) - 结构体的内存分析
- C 语言函数返回结构体汇编分析
- 对C语言中结构体的测试分析
- 8583报文结构分析及C语言实现
- C语言返回值为结构体的汇编分析
- C语言内存中结构体对齐分析
- C语言结构体做参数易错情况分析
- c语言中结构体占用内存分析
- C语言以数组和结构体传参
- C语言中的结构
- C语言结构体
- C语言:结构体
- C语言字段结构
- C语言:结构体
- C语言语句结构
- Server.MapPath详解(转)
- constraint用法总结 II
- 初识 UNIX
- define和typedef的一个小例子
- sqlserver2008 文件流
- C语言结构体传参分析
- Winform中TreeView的绑定
- 学习所得
- jquery随记(DOM操作)----插入元素
- 不同OS下调用参数的不同
- 一个强大的父类:BaseDao
- FileUpload1文件上传
- eclipse中的快捷键
- MyISAM InnoDB 区别