Printf 不定参

本文介绍了C语言中处理不定参数的方法,包括规定、ARM和51架构下的参数传递、如何确定不定参数个数,以及如何在实际编程中使用不定参数。通过分析printf函数,阐述了如何利用堆栈和宏来操作不定参数地址,并提供了相关的代码示例。
摘要由CSDN通过智能技术生成

Printf 不定参

一些规定
  • 不定参数的列表必须在整个函数的参数列表的最后
  • 函数调用时参数传递是使用堆栈来实现的
  • 在51 和arm中,不论怎么传递参数,都确保是向下生长的栈(51是模拟的一个),第一个参数在最低地址即可,否则如果是向上生长的堆栈,取参数的宏就需要做改变了
ARM传递参数
  • 当少于四个时,按从左到右的顺序依次放在r0,r1,r2,r3中;
  • 当多于四个时,前四个放在r0,r1,r2,r3中,剩余的放在堆栈中,最后一个参数先入栈,第五个参数最后入栈,即从右到左入栈

例子如下:,传递参数先在r0,r1,r2,r3,然后放进栈中

    48:            testStack("1",(int)2,(int)3,(int)4,(int)5,(int)6,(int)7,(int)8,(int)9,(int)10,(int)11,(int)12,(int)13); 
0x0800028A 200D      MOVS     r0,#0x0D
0x0800028C 210C      MOVS     r1,#0x0C
0x0800028E 220B      MOVS     r2,#0x0B
0x08000290 230A      MOVS     r3,#0x0A
0x08000292 E9CD3205  STRD     r3,r2,[sp,#0x14]
0x08000296 E9CD1007  STRD     r1,r0,[sp,#0x1C]
0x0800029A 2009      MOVS     r0,#0x09
0x0800029C 2108      MOVS     r1,#0x08
0x0800029E 2207      MOVS     r2,#0x07
0x080002A0 2306      MOVS     r3,#0x06
0x080002A2 E9CD3201  STRD     r3,r2,[sp,#0x04]
0x080002A6 E9CD1003  STRD     r1,r0,[sp,#0x0C]
0x080002AA 2005      MOVS     r0,#0x05
0x080002AC 2304      MOVS     r3,#0x04
0x080002AE 2203      MOVS     r2,#0x03
0x080002B0 2102      MOVS     r1,#0x02
0x080002B2 9000      STR      r0,[sp,#0x00]
0x080002B4 A014      ADR      r0,{pc}+4  ; @0x08000308
0x080002B6 F7FFFFBD  BL.W     testStack (0x08000234)

使用时直接用堆栈,取出r0~~r3的值

    10: void testStack(char * format, ...) 
0x08000232 4770      BX       lr
    11: { 
0x08000234 B40F      PUSH     {r0-r3}
0x08000236 B570      PUSH     {r4-r6,lr}
    12:         char *p = (char * )&format; 
    13:         int i; 
    14:         int b; 
    15:  
    16:          
0x08000238 AC04      ADD      r4,sp,#0x10

.........................

当参数个数较少时, 可能也就单纯的赋值到r0~~r3

#include "stdio.h"

int  a1(int b)
{
  return (b)+1;
}


long  a[10];
void SystemInit(){;}
void testStack(int format, ...)
{
    char *p = (char * )&format;
    int i;
    int b;
    a[0]=format;
    a[1]=(long)&format;
    p = p + sizeof(int);

    b=(int)p;
    a1(b);

    i = *((int *)p);
    a[
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值