printf在是一个标准库函数,功能是:打印(变量、字符串)等等。
问题:能不能依据printf的原理,写一个简易的用于裸机程序调试的my_printf函数呢?
好处:1)my_printf函数在单片机、嵌入式芯片裸机调试过程中非常方便。
2)my_printf函数可以帮你打印寄存器的值、变量的值、打印字符串等。
printf的声明:
int printf(const char *format, ...);
format:固定参数
... :可变参数(变参)
printf中的格式字符
例程1+内存解读:
例程2+内存解读:
/*
* push_test.c V1.0
* Copyright (c) 2017 Shenzhen 100ask Technology Co.Ltd.All rights reserved.
* http://www.100ask.org
* 100ask.taobao.com
*
* 测试平台: ubuntu16.04(64位机器)
* ubuntu9.10 (32位机器)
* 编译器 : gcc
*/
#include <stdio.h>
struct person{
char *name;
int age;
char score;
int id;
};
/*
*int printf(const char *format, ...);
*依据:x86平台,函数调用时参数传递是使用堆栈来实现的
*目的:将所有传入的参数全部打印出来
*/
int push_test(const char *format, ...)
{
char *p = (char *)&format;
int i;
struct person per;
char c;
double d;
printf("arg1 : %s\n",format);
//==============
/*指针对连续空间操作时: 1) 取值 2)移动指针*/
p = p + sizeof(char *);
i = *((int *)p);
printf("arg2 : %d\n",i);
//==============
/*指针对连续空间操作时: 1) 取值 2)移动指针*/
p = p + sizeof(int);
per = *((struct person *)p);
printf("arg3: .name = %s, .age = %d, .socre=%c .id=%d\n",\
per.name, per.age, per.score, per.id);
//==============
/*指针对连续空间操作时: 1) 取值 2)移动指针*/
p = p + sizeof(struct person);
c = *((char *)p);
printf("arg4: %c\n",c);
//==============
/*指针对连续空间操作时: 1) 取值 2)移动指针*/
p = p + ((sizeof(char) + 3) & ~3);
//当sizeof(n)=1/2/4时,_INTSIZEOF(n)等于4
//#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
d = *((double *)p);
printf("arg5: %f\n",d);
return 0;
}
int main(int argc,char **argv)
{
struct person per={"www.100ask.org",10,'A',123};
printf("sizeof(char )=%d\n",sizeof(char ));
printf("sizeof(int )=%d\n",sizeof(int ));
printf("sizeof(char *)=%d\n",sizeof(char *));
printf("sizeof(char **)=%d\n",sizeof(char **));
printf("sizeof(struct person)=%d\n",sizeof(struct person));
//push_test("abcd");
//push_test("abcd",123);
//push_test("abcd",123,per);
//push_test("abcd",123,per,'c');
push_test("abcd",123,per,'c',2.79);
return 0;
}
关于四字节对齐:见转载文章
https://blog.csdn.net/weixin_44189360/article/details/108045863
关于强制对齐:
可以通过使用gcc中的__attribute__选项来设置指定的对齐大小。
1:
__attribute__ ((packed)),让所作用的结构体取消在编译过程中的优化对齐,
按照实际占用字节数进行对齐。
2:
__attribute((aligned (n))),让所作用的结构体成员对齐在n字节边界上。
如果结构体中有成员变量的字节长度大于n,
则按照最大成员变量的字节长度来对齐。
struct person1{
char *name;
int age;
char score;
int id;
}__attribute__ ((packed));
struct person2{
char *name;
int age;
char score;
int id;
}__attribute((aligned (4)));