可变参数函数printf的实现(不使用va_list等内置宏定义)
来源:互联网 发布:网络怎么赚钱最快 编辑:程序博客网 时间:2024/06/06 04:20
一直好奇c语言中int printf( const char* format, …) 可变参数函数是怎样实现的,网上关于可变参数函数的实现基本上使用了va_list,va_start,va_end等内置宏定义,为了更深入的理解可变参数函数,决定直接使用内置汇编来实现关键操作。
1.可变参数函数的形参使用(…)来表示可变个数的参数,在实际调用时,所有的参数都会被压入栈中,需要自行从栈中读取参数,这只能使用内置汇编来实现了。关键汇编代码如下:
asm("pushl %%ebp;addl %1,%%ebp;movl (%%ebp),%%eax;popl %%ebp;":"=a"(v):"m"(offset));
my_printf.c
#include <stdio.h>#define is_digit(c) ((c) >= '0' && (c) <= '9')//#define NULL ((void *) 0)static int my_atoi(const char *s){ int i=0; while (is_digit(*s)) i = i*10 + *(s++) - '0'; return i;}static int my_itoa(const int v,char *s){ int yi=0,result=0,a=v; char c[11]; if(a==0){ s[0]='0',s[1]='\0'; return 1; } while(a!=0){ yi=a%10; a=a/10; result++; c[result]=(char)(yi+48); } s[result]='\0'; int i=0; for(i=result;i>0;i--)s[result-i]=c[i]; return result;}static int my_itox(const int v,char *s){ int yi=0,result=0,value=v; char c[8]={'0','0','0','0','0','0','0','0'}; if(value!=0){ while(value!=0){ yi=value%16; if(yi>9){ yi=yi-9; c[result]=(char)(yi+64); }else{ c[result]=(char)(yi+48); } value=value/16; result++; } }else{ s[0]='0',s[1]='\0'; return 1; } c[result]='\0'; s[result]='\0'; int i=0; for(i=result;i>0;i--)s[result-i]=c[i-1]; return result;}int my_strcpy(char *des,char *src,int skip){ int i=0; char *p=src; while(*p!='\0'){ des[skip+(i++)]=*(p++); } return i;}static int my_strlen(const char *s){ int i=0; while(*(s++)!='\0')i++; return i;}static int my_printf(const char *fmt, ...){ int num=1; int buf_index=0; char buf[1024]={'0'};//存储将打印到屏幕的字符串 char* p=fmt; while(*p!='\0'){ buf[buf_index++]=*p; if(*p=='%'){ buf_index--; p++; switch (*p){ case 'd':{ int v=0; char a[10]; int offset=num*4+8; asm("pushl %%ebp;addl %1,%%ebp;movl (%%ebp),%%eax;popl %%ebp;":"=a"(v):"m"(offset)); int len=my_itoa(v,a); my_strcpy(buf,a,buf_index); buf_index=buf_index+len; break; } case 'c':{ int v=0; int offset=num*4+8; asm("pushl %%ebp;addl %1,%%ebp;movl (%%ebp),%%eax;popl %%ebp;":"=a"(v):"m"(offset)); buf[buf_index]=(char)v; buf_index=buf_index+1; break; } case 's':{ char* v=NULL; int offset=num*4+8; asm("pushl %%ebp;addl %1,%%ebp;movl (%%ebp),%%eax;popl %%ebp;":"=a"(v):"m"(offset)); int vlen=my_strcpy(buf,v,buf_index); buf_index=buf_index+vlen; break; } case 'x':{ int v=0; char a[10]; int offset=num*4+8; asm("pushl %%ebp;addl %1,%%ebp;movl (%%ebp),%%eax;popl %%ebp;":"=a"(v):"m"(offset)); int len=my_itox(v,a); my_strcpy(buf,a,buf_index); buf_index=buf_index+len; break; } default: break; }//switch num++;//²ÎÊý¸öÊý }//if p++; }//while buf[buf_index]='\0'; printf("\n%s",buf); return buf_index;}int main(){ my_printf("a=%d,b=%x,d=%c,s=%s",322343,0xabcd,'A',"hello\n"); return 0;}
0 0
- 可变参数函数printf的实现(不使用va_list等内置宏定义)
- va_list、va_start、va_arg、va_end等利用宏定义实现可变参数
- va_list、va_start、va_end(用于实现函数参数的个数可变的函数,如scanf()/printf()系列函数)
- va_list可变参数的函数
- va_start、va_end、va_list等可变参数的使用
- va_list,可变参数的使用
- C语言利用va_list、va_start、va_end、va_arg宏定义可变参数的函数
- printf谈可变参数函数的实现
- printf函数可变参数的实现
- OC可变参数的函数实现va_start、va_end、va_list的使用
- C/C++中va_list,va_start,va_arg,va_end等可变参数宏的使用
- 可变参数函数的使用:va_start() , va_end() , va_list
- 可变参数的使用-printf简单实现
- 可变参数:printf函数实现
- vsprintf,va_list可变参数的使用
- 可变参数va_list的理解和使用
- C++可变长参数va_list的使用
- printf可变参数的实现
- sdut2117数据结构实验之链表二:逆序建立链表
- LintCode:回文串
- AngularJS: Date filtering and formatting
- 第一次博客呀
- Java学习(一)基础知识点
- 可变参数函数printf的实现(不使用va_list等内置宏定义)
- 卡尔曼滤波理解(转载)
- sdut2118数据结构实验之链表三:链表的逆置
- PYTHON组合
- linux 快速安装Mysql
- Ubuntu下安装UDK
- angularJS DOM操作相关指令
- Vue2.0项目升级(2-ubuntu下习惯设置)
- 坚持#第88天~规范!