STM8S的配置字节OptionByte

STM8S的配置字节OptionByte
STM8S的配置字节OptionByte

8S

T M S

-

E K STM8S 的配置字节OPTION BYTE

这一章节我们将详细说明一下STM8S 的OptionByte 。在此只以STM8S -EK 开发板上的主控制芯片STM8S208R8做为目标芯片来讲解。本章主要解决以下问题:

1.什么是STM8S 的配置字 OptionByte

2.Option Byte 里面的位都表示什么

3.如何编程Option Byte

一 选项字节(OptionByte )

AFR7=1AFR7=0当然,任何的配置,用户还是可以像普通的IO 一样来使用PD4。

(理论上)

STM8S 的配置字类似于AVR 的Fuse 熔丝位。用于配置端口的复用功能和读保护等操作。不同于AVR 的熔丝位,STM8S 的时钟配置并不在Option Byte 中,不会出现写完STM8S 后芯片直接锁死的尴尬。

选项字节用于配置硬件特性和存储器保护状态,这些字节位于同一页的特定存储器阵列中。 选项字节可以在ICP/SWIM模式中或IAP模式中修改, 也就是可以通过STlink 写配置字,或者是通过程序写选项字。

,STM8S 的有一个蜂鸣器控制器BEEP ,这BEEP 对应的端口是PD4.但是PD4有两个复用功能,它可以是

BEEP 蜂鸣器的输出

Tim2 比较输出1 也就是Tim2_CC1

用户必须在这两个功能中选择一个,只能选择一个。那如何使PD4是BEEP 输出呢?

答案是通过设置Option byte 选项字,将AFR7配置成1,使用PD4输出的是BEEP 的信号,否则,PD4将输出的是Tim2_CC1的信号 。

Option Byte 除了能够配置端口的复用功能外,它还可以设置芯片的当选项字节中的ROP字节被编程为’0xAA’时,读保护就生效了。这种情况下,无论写保护是否生效,在ICP模式中(使用SWIM接口)读取或修改FLASH程序存储器和DATA区域都是被禁止的。即使认为没有什么保护是完全不可破解的,对于一个通用微处理器来说,STM8的读保护的特性也提供了一个非常高水平的保护级别。

也就是说,防止别人拷贝你的程序的方法可以是编程ROP 字节以使能读保护,那么 对方无论如何都不能从STM8中读到你的Flash 数据当需要开启端口的第二功能时,需要考虑选项字节的编程,否则将不能实现程序所想要的功能。

例如1.2.读保护

7

https://www.360docs.net/doc/2b385462.html,

STM8S -EK 开发板例程

九单片机论坛

w w w .9m c u .c o m

二 选项字节详解

仍然以STM8S208R8为例,看一下它可配置的选项字节通过前面的介绍 你应该对OptionByte 是做什么用有一个初步的认识了。那么,下面我们来讲一下,如何用OptionByte 。OptionByte 具体和我的工程有什么关系呢?

下图就是从STVP里截图到的

读保护

用户启动区域大小

端口复用选择

低频时钟看门狗

时钟设置

时钟稳定时间

Flash 等待时钟

Bootloader 使能

OPT0:ROP 读保护

STM8可以直接修改ROP ,解除读保护,这会引起:程序存储器、UBC、DATA区域以及选项字节都被自动擦除

这个是整个Flash 的读保护使能或者是失能位,当这个字节等于 AA 时,读保护生效,用户将不能读出Flash 内部的信息。并不意谓着这个芯片就废了,不像AVR 还需要高压编程来恢复Fuse .这样一来,芯片就等于出厂时的设置了,器件也可以被重新编程了。

当前值

九单片机论坛

w w w .9m c u .c o m

OPT4:时钟选项

EXTCLK CKAWUSEL PRSC 外部时钟连接的硬件 两个可能:

1.外部晶体/陶瓷谐振器 外部时钟连接的是两脚的晶体,需要芯片启动时钟

2.外部时钟是一个信号源 输入占空比约50%的外部时钟信号(方波,正弦波,三角波)用以驱动OSCIN引脚,而OSCOUT引脚可做为通用输入/输出管脚使用。

自动唤醒单元(AWU)的时钟源,可以选择1.内部低频率时钟LSI 做为AWU 的时钟

2.高频时钟HSE 经过分频后做为AWU 的时钟

HSE 的分频值可通过选项字节位HSEPRSC[1:0]编程。这里分出来的时钟是给AWU 单元的

OPT5:HSECNT启动稳定时钟数

2048-0x05 = 2043个周期J 外部晶体振荡器在启动时的输出时钟信号是不稳定的,默认情况下,在时钟信号被使用之前会插入2048个振荡器周期的延迟。用户可通过设置选项字节

HSECNT来缩短稳定时间。也就是说,这个字节的值将决定振荡器周期的延迟,当这个字节为0x05时,那么振荡器周期的延迟将是:其他的值依此类推

EXTCLK =1

EXTCLK =0

九单片机论坛

w w w .9m c u .c o m

通过程序修改选项字节

对选项字节编程和对DATA EEPROM 区域编程非常相似。Option Byte 的存放地址位于0x4800-0x487F 之间

下面是STM8S208R8的OptionByte 对应的地址表。除了ROP 字节外,其他的都由两个字节组成

选项字节存放于数据 EEPROM 中,所以我们可以通过读写EEPROM 一样的操作来修改选项字节。

应用程序可直接向目标地址进行写操作。利用STM8的RWW 功能,在对选项字节写操作的同时程序不必停下来。

建议尽量不要在程序中修改OPTION Byte 因为,假如程序跑飞产生错误的OptionByte ,那对你的系统将是一个灾难。

九单片机论坛

w w w .9m c u .c o m

STM8S -EK

www https://www.360docs.net/doc/2b385462.html,

作者: lisn3188

E -mail :lisn3188@https://www.360docs.net/doc/2b385462.html, STM8S -EK 开发板唯一销售网址:https://www.360docs.net/doc/2b385462.html,/

九单片机论坛

w w w .9m c u .c o m

sizeof进行结构体大小的判断

sizeof进行结构体大小的判断 typedef struct { int a; char b; }A_t; typedef struct { int a; char b; char c; }B_t; typedef struct { char a; int b; char c; }C_t; void main() { char*a=0; cout<

2. 语法: sizeof有三种语法形式,如下: 1) sizeof( object ); // sizeof( 对象); 2) sizeof( type_name ); // sizeof( 类型); 3) sizeof object; // sizeof 对象; 5. 指针变量的sizeof 既然是来存放地址的,那么它当然等于计算机内部地址总线的宽度。所以在32位计算机中,一 个指针变量的返回值必定是4(以字节为单位),可以预计,在将来的64位系统中指针变量的sizeof结果为8。 char* pc = "abc"; int* pi; string* ps; char** ppc = &pc; void (*pf)();// 函数指针 sizeof( pc ); // 结果为4 sizeof( pi ); // 结果为4 sizeof( ps ); // 结果为4 sizeof( ppc ); // 结果为4 sizeof( pf );// 结果为4 指针变量的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针变量所占内存大小相等,所以MFC消息处理函数使用两个参数WPARAM、LPARAM 就能传递各种复杂的消息结构(使用指向结构体的指针)。 6. 数组的sizeof 数组的sizeof值等于数组所占用的内存字节数,如: char a1[] = "abc"; int a2[3];

初中数学几何空间与图形知识点

初中数学《几何空间与图形》知识点 初中数学《几何空间与图形》知识点 A、图形的认识 1、点,线,面 点,线,面:图形是由点,线,面构成的。面与面相交得线,线与线相交得点。点动成线,线动成面,面动成体。 展开与折叠:在棱柱中,任何相邻的两个面的交线叫做棱,侧棱是相邻两个侧面的交线,棱柱的所有侧棱长相等,棱柱的上下底面的形状相同,侧面的形状都是长方体。N棱柱就是底面图形有N条边的棱柱。截一个几何体:用一个平面去截一个图形,截出的面叫做截面。 视图:主视图,左视图,俯视图。 多边形:他们是由一些不在同一条直线上的线段依次首尾相连组成的封闭图形。 弧、扇形:由一条弧和经过这条弧的端点的两条半径所组成的图形叫扇形。圆可以分割成若干个扇形。 2、角 线:线段有两个端点。将线段向一个方向无限延长就形成了射线。射线只有一个端点。将线段的两端无限延长就形成了直线。直线没有端点。经过两点有且只有一条直线。 比较长短:两点之间的所有连线中,线段最短。两点之间线段的长度,叫做这两点之间的距离。 角的度量与表示:角由两条具有公共端点的射线组成,两条射线的公共端点是这个角的顶点。一度的1/60是一分,一分的1/60是一秒。角的比较:角也可以看成是由一条射线绕着他的端点旋转而成的。一条射线绕着他的端点旋转,当终边和始边成一条直线时,所成的角叫做平角。始边继续旋转,当他又和始边重合时,所成的角叫做周角。从一个角的顶点引出的一条射线,把这个角分成两个相等的角,这条射线叫做这个角的平分线。 平行:同一平面内,不相交的两条直线叫做平行线。经过直线外一点,有且只有一条直线与这条直线平行。如果两条直线都与第3条直线平行,那么这两条直线互相平行。

C 语言中 地址对齐与数据对齐

------------------------------Editor: JaceLin-----------------Date: 2014.2.7--------------------------- C语言中的地址&数据对齐 NOTE: 在单片机开发中,不论是什么样的单片机,打开官方头文件都会发现,里面全是各种各样的结构体(struct)与宏定义(define),但不论定义的字母多么长多么难懂,它们的最终映像都是一个16进制的地址。对于一个单片机初学者来说,看到这些定义往往会很头痛,因为平时基本都是用别人的头文件,很少去写自己的单片机头文件。 前几天一直在写一个freescal K60单片机DMA程序,DMA就是‘直接对寄存器存取’,顾名思义,这个程序要涉及寄存器的操作(其实所有的单片机程序都是操作寄存器,只是定义了宏不直观而已)!DMA对于我来说第一次接触,中间就接触到了许多关于前面所说的官方给的struct与define,但是我感觉他们写的都很啰嗦过于繁琐,于是为了简化程序,我不得不弄清楚这些定义到底是什么意思。我专门去网上找了很多关于这方面的资料,最后我得出结论,其实就是两个方面内容:地址对齐与数据对齐! 下面就让我来解读这些难懂的struct & define. 一、数据对齐(以下内容都以32bit x86/arm平台为例) 在没有#progma pack(n)参数的情况下: 例1: struct A{ char a; char b; char c; }; Sixeof(struct A) =多少? 分析:一个char 长度为1个字节,而内存单元为4个字节,以上struct A 占用内存如下图:

内存对齐方式

对齐方式 为什么会有内存对齐? 在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间;各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。在缺省情况下,C编译器为每一个变量或数据单元按其自然对界条件分配空间。 字,双字,和四字在自然边界上不需要在内存中对齐。(对字,双字,和四字来说,自然边界分别是偶数地址,可以被4整除的地址,和可以被8整除的地址。)无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。 一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问。 某些操作双四字的指令需要内存操作数在自然边界上对齐。如果操作数没有对齐,这些指令将会产生一个通用保护异常(#GP)。双四字的自然边界是能够被16整除的地址。其他的操作双四字的指令允许未对齐的访问(不会产生通用保护异常),然而,需要额外的内存总线周期来访问内存中未对齐的数据。 影响结构体的sizeof的因素: 1)不同的系统(如32位或16位系统):不同的系统下int等类型的长度是变化的,如对于16位系统,int的长度(字节)为2,而在32位系统下,int的长度为4;因此如果结构体中有int等类型的成员,在不同的系统中得到的sizeof值是不相同的。 2)编译器设置中的对齐方式:对齐方式的作用常常会让我们对结构体的sizeof 值感到惊讶,编译器默认都是8字节对齐。 对齐: 为了能使CPU对变量进行高效快速的访问,变量的起始地址应该具有某些特性,即所谓的“对齐”。例如对于4字节的int类型变量,其起始地址应位于4字节边界上,即起始地址能够被4整除。变量的对齐规则如下(32位系统)

结构体对齐

关于 C 语言中的结构体对齐 (1)什么是字节对齐 一个变量占用 n 个字节,则该变量的起始地址必须能够被n 整除,即: 存放起始地址 % n = 0 ,对于结构体而言,这个 n 取其成员种的数据类型占空间的值最大的那个。 (2)为什么要字节对齐 内存空间是按照字节来划分的,从理论上说对内存空间的访问可以从任何地址开始,但是在实际上不同架构的 CPU 为了提高访问内存的速度,就规定了对于某些类型的数据只能从特定的起始位置开始访问。这样就决定了各种数据类型只能按照相应的规则在内存空间中存放,而不能一个接一个的顺序排列。 举个例子,比如有些平台访问内存地址都从偶数地址开始,对于一个 int 型( 假设 32 位系统 ),如果从偶数地址开始的地方存放,这样一个读周期就可以读出这个 int 数据,但是如果从奇数地址开始的地址存放,就需要两个读周期,并对两次读出的结果的高低字节进行拼凑才能得到这个 int 数据,这样明显降低了读取的效率。 (3)如何进行字节对齐 每个成员按其类型的对齐参数 (通常是这个类型的大小 )和指定对齐参数 ( 不指定则取默认值 ) 中较小的一个对齐,并且结构的长度必须为所用过的所有对齐参数的整数倍 ,不够就补空字节。 这个规则有点苦涩,可以把这个规则分解一下,前半句的意思先获得对齐值后与指定对齐值进行比较 ,其中对齐值获得方式如下:

1. 数据类型的自身对齐值为:对于 char 型数据,其自身对齐值为 1 ,对于 short 型为 2 ,对于 int, long, float 类型,其自身对齐值为 4 ,对于 double 类型其自身对齐值为 8 ,单位为字节。 2. 结构体自身对齐值:其成员中自身对齐值最大的那个值。 其中指定对齐值获得方式如下: #pragma pack (value) 时的指定对齐值 value 。 未指定则取默认值。 后半句的意思是主要是针对于结构体的长度而言,因为针对数据类型的成员,它仅有一个对齐参数,其本身的长度、于这个对齐参数,即 1 倍。对于结构体而言,它可能使用了多种数据类型,那么这句话翻译成对齐规则:每个成员的起始地址 % 自身对齐值 = 0 ,如果不等于0 则先补空字节直至这个表达式成立。 换句话说,对于结构体而言,结构体在在内存的存放顺序用如下规则即可映射出来: ( 一)每个成员的起始地址 % 每个成员的自身对齐值 = 0 ,如果不等于 0 则先补空字节直至这个表达式成立; ( 二 ) 结构体的长度必须为结构体的自身对齐值的整数倍, 不够就补空字节。 举个例子: #pragmapack(8) structA{ chara; longb; }; structB{

【小学数学】人教版五年级下册数学空间与图形知识点汇总

人教版五年级下册数学空间与图形知识点汇总 一、轴对称与旋转 1、图形的变换包括平移、旋转和对称。 2、轴对称图形:一个图形沿某一条直线对折;直线两侧的图形能够完全重合;这个图形就是轴对称图形。这条直线叫做它的对称轴。 3、轴对称图形都有对称轴。有一条对称轴的图形有等腰三角形;等腰梯形、线段、角。有两条对称轴的图形有长方形、菱形。有三条对称轴的图形有正三角形。正方形有4条对称轴。 4、轴对称图形的特征: (1)、对应点到对称轴的距离相等; (2)、对应点连线与对称轴互相垂直。 5、轴对称图形的画法: (1)、找出已知图形的关键点。 (2)、在对称轴的另一侧画出关键点的对应点。 (3)、按顺序连接各对应点。 6、旋转:图形或物体绕着一个点或一条轴运动的现象叫做旋转。图形旋转后只改变位置;不改变形状和大小。 一、长方体和正方体的认识 在3个、4个、5个面是正方形!

练习: (1)判断并改正: 1、长方体的六个面一定是长方形; ( ) 2、正方体的六个面面积一定相等; ( ) 3、一个长方体(非正方体) 最多有四个面面积相等; ( ) 4、相交于一个顶点的三条棱相等的长方体一定是正方体。 ( ) 7、长方体的三条棱分别叫做长、宽、高。 ( ) 8、有两个面是正方形的长方体一定是正方体。( ) 9、有三个面是正方形的长方体一定是正方体。( ) 11、有两个相对的面是正方形的长方体;另外四个面的面积是相等的。( ) 12、长方体和正方体最多可以看到3个面。( ) 14、正方体不仅相对的面的面积相等;而且所有相邻的面的面积也都相等。( ) 15、长方体(不包括正方体)除了相对的面相等;也可能有两个相邻的面相等。 ( ) 16、一个长方体中最少有4条棱长度相等;最多有8条棱长度相等。( ) (2)填空: 1、一个长方体最多有( )个面是正方形;最多有( )条棱长度相等。 2、一个长方体的底面是一个正方形;则它的4个侧面是 ( )形。 3、 正方体不仅相对的面相等;而且所有相邻的面( );它的六 个面都是相等的( )形。 4、 把长方体放在桌面上;最多可以看到( )个面。最少可以看 到( )个面。 【知识点2】 棱长和公式:长方体棱长和=(长+宽+高)×4 长+宽+高=棱长和÷4 长方体棱长和= 下面周长×2+高×4 长方体棱长和=右面周长×2+长×4 长方体棱长和=前面周长×2+宽×4 正方体棱长和=棱长×12 棱长=棱长和÷12 棱长和的变形: 例如:有一个礼盒需要用彩带捆扎;捆扎效果如图;打结部分需要10厘米彩带;一共需要多长的彩带? 分析:本题虽然并未直接提出求棱长和;但由 于彩带的捆扎是和棱相互平行的; 因此;在解决问题时首先确定每部分彩带 与那条棱平行;从而间接去求棱长和。 前面和后面的彩带长度=高的长度;左面和右 面的彩带长度=高的长度; 上面和下面的彩带长度=长的长度。 需要彩带的长度=高×4+长×2+宽×2+打结部分长度 20×4+30×2+10=150cm

c++中关于结构体长度的计算问题

[C++]字节对齐与结构体大小 [C++] 2010-09-24 21:40:26 阅读172 评论0 字号:大中小订阅 说明: 结构体的sizeof值,并不是简单的将其中各元素所占字节相加,而是要考虑到存储空间的字节对齐问题。这些问题在平时编程的时候也确实不怎么用到,但在一些笔试面试题目中出是常常出现,对sizeof我们将在另一篇文章中总结,这篇文章我们只总结结构体的sizeof,报着不到黄河心不死的决心,终于完成了总结,也算是小有收获,拿出来于大家分享,如果有什么错误或者没有理解透的地方还望能得到提点,也不至于误导他人。 一、解释 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如

有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int 型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。 二、准则 其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则: 1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节; 3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。 三、基本概念

内存字节对齐

1.内存字节对齐和小端模式: /* 本程序是关于:编译器内存的字节对齐方式和存储时的小端对齐模式(win7 32bit) #pragma pack(n) 默认为8字节对齐,(即n=8)其中n的取值为1,2,4,8,16,32等 内存字节对齐大小和方式: 1)结构体内变量对齐: 每个变量的对齐字节数大小argAlignsize=min(#pragma pack(n),sizeof(变量)); 方式:结构体的第一个变量的初始偏移地址为0,其它变量的偏移地址(当前变量的起始地址)必须是argAlignsize的整数倍,不够整数倍的补空,不添加任何数据 2)结构体对齐: 结构体的对齐字节数大小strAlignsize=min(#pragma pack(n),sizeof(所有变量中最大字节的变量)) 方式: A.对于单独的结构体来说,结构体本身按照strAlignsize大小来对齐 B.结构体B在结构体A中时,结构体B的起始地址是结构体B的 strAlignsize大小的整数倍 小端对齐模式: 指针指着一个存储空间,存储空间地址由低到高的存储内容为:0x78,0x67,0x33,0x45 若指针为char,则获取的数据为0x78 若指针为short,则获取的数据为0x6778 若指针为long,则获取的数据为0x45336778 */ #include using namespace std; /*更改C编译器内存的缺省字节对齐方式,由默认的n=4字节,变为n字节对齐,其中n的取值为1,2,4,8,16,32等*/ #pragma pack(2) struct A { unsigned char a; unsigned short b; }; struct B { unsigned char c; unsigned int d;

初中几何空间与图形知识点

初中几何空间与图形知识点 A、图形的认识 1、点,线,面 点,线,面:①图形是由点,线,面构成的。②面与面相交得线,线与线相交得点。③点动成线,线动成面,面动成体。展开与折叠:①在棱柱中,任何相邻的两个面的交线叫做棱,侧棱是相邻两个侧面的交线,棱柱的所有侧棱长相等,棱柱的上下底面的形状相同,侧面的形状都是长方体。②N棱柱就是底面图形有N条边的棱柱。 截一个几何体:用一个平面去截一个图形,截出的面叫做截面。 视图:主视图,左视图,俯视图。 多边形:他们是由一些不在同一条直线上的线段依次首尾相连组成的封闭图形。 弧、扇形:①由一条弧和经过这条弧的端点的两条半径所组成的图形叫扇形。②圆可以分割成若干个扇形。 2、角 线:①线段有两个端点。②将线段向一个方向无限延长就形成了射线。射线只有一个端点。③将线段的两端无限延长就形成了直线。直线没有端点。④经过两点有且只有一条直线。比较长短:①两点之间的所有连线中,线段最短。②两点之间线段的长度,叫做这两点之间的距离。

角的度量与表示:①角由两条具有公共端点的射线组成,两条射线的公共端点是这个角的顶点。②一度的1/60是一分,一分的1/60是一秒。 角的比较:①角也可以看成是由一条射线绕着他的端点旋转而成的。②一条射线绕着他的端点旋转,当终边和始边成一条直线时,所成的角叫做平角。始边继续旋转,当他又和始边重合时,所成的角叫做周角。③从一个角的顶点引出的一条射线,把这个角分成两个相等的角,这条射线叫做这个角的平分线。 平行:①同一平面内,不相交的两条直线叫做平行线。②经过直线外一点,有且只有一条直线与这条直线平行。③如果两条直线都与第3条直线平行,那么这两条直线互相平行。垂直:①如果两条直线相交成直角,那么这两条直线互相垂直。②互相垂直的两条直线的交点叫做垂足。③平面内,过一点有且只有一条直线与已知直线垂直。 垂直平分线:垂直和平分一条线段的直线叫垂直平分线。 垂直平分线垂直平分的一定是线段,不能是射线或直线,这根据射线和直线可以无限延长有关,再看后面的,垂直平分线是一条直线,所以在画垂直平分线的时候,确定了2点后(关于画法,后面会讲)一定要把线段穿出2点。 垂直平分线定理: 性质定理:在垂直平分线上的点到该线段两端点的距离相

C语言内存对齐

解析C语言结构体对齐(内存对齐问题) C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢? 开始学的时候,也被此类问题困扰很久。其实相关的文章很多,感觉说清楚的不多。结构体到底怎样对齐? 有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下): 原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。 原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。) 原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。 这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。 例1:struct { short a1; short a2; short a3; }A; struct{ long a1; short a2; }B; sizeof(A) = 6; 这个很好理解,三个short都为2。 sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。 例2:struct A{ int a; char b; short c; }; struct B{ char b; int a; short c; }; sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。 sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。

C语言结构体的字节对齐及指定对齐方式

内存中结构体的内存对齐 一、字节对齐作用和原因: 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐,其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit 数据,显然在读取效率上下降很多。 二、字节对齐规则: 四个重要的概念: 1.数据类型自身的对齐值:对于char型的数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4个字节。 2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。 3.指定对齐值:#pragma pack (value)时指定的对齐value。 4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。补充: 1).每个成员分别按自己的方式对齐,并能最小化长度。 2).复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。 3).对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。 #pragma pack(1) struct test { static int a; //static var double m4; char m1; int m3; } #pragma pack() //sizeof(test)=13;

空间与图形知识点整理与习题

来源:网络 2009-07-27 10:02:14 [标签:图形总复习六年级苏教版数学]奥数精华资讯免费订阅 教学内容:义务教育课程标准实验教科书97-98页“整理与反思”和“练习与实践”7 -10题。 教学目标: 1、通过复习,使学生加深对长方形.正方形.平行四边形.梯形.三角形和圆等平面图形基本特征的认识。 2、能用所学的知识解决一些简单的实际问题。 教学重点、难点:用所学的知识解决一些简单的实际问题。 教学设计: 一、整理与复习 1.提出要求:请大家回忆,我们学过哪些围成的平面图形?先画出相关的图形,再在小组里交流一下。 2.进一步要求;如果把这些平面图形分成两类,可以怎样分? 引导学生认识到:由线段围成的平面图形分为一类,由曲线或由曲线和线段共同围成平面图形分为一类。 3.追问:由线段围成的平面图形都可称为什么图形?如果把多边形进一步分类,可以怎样分? 4.让学生在画出的三角形.平行四边形和梯形上作高,在画出的圆中用字母标出圆心.半径和直径。 二、复习三角形的知识 1、三角形的概念。 “我们已经学过三角形,请同学们自己画出几种不同的三角形。”教师巡视。

“大家已经会画三角形了,说一说三角形是什么样的图形。”(三角形是由三条线段围成的图形。) “三角形具有什么特性?日常生活中哪些地方用到这一特性?” “在三角形中一个顶点的对边是哪一条边?看一看自己画的三角形,指一下每个顶点的对边。” “想一想三角形的高指的是什么,怎样画一个三角形的高。”教师巡视,检查学生的画法是否正确。 2、三角形的分类。 “同学们刚才画了几种不同的三角形,它们有什么不同?是按照什么标准分类的?”(两种标准:按角分类,按边分类。) “按照三角形中角的不同可以把三角形分成几类?它们分别叫做什么三角形?” (可以把三角形分成三类:锐角三角形、直角三角形和钝角三角形。) “每类三角形的三个角各是什么角?” “我们学过什么特殊的三角形?”(等边三角形和等腰三角形。) 3.出示三角形的集合图 提问:你是怎样理解上面这个图形的? 什么样的三角形是等腰三角形?什么样的三角形是等边三角形? 判断下面说法是否正确: (1)等边三角形一定是等腰三角形。() (2)等腰三角形一定是等边三角形?两边之和大于第三边。 你能用学过的其他知识来解释上面的结论吗? 4.完成“练习与实践”第8.9题 第8题让学生先独立选一选,再要求说说选择时是怎样想的。

C语言结构体对齐

C语言结构体对齐 C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢? 开始学的时候,也被此类问题困扰很久。其实相关的文章很多,感觉说清楚的不多。结构体到底怎样对齐? 有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下): 原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。 原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b 里有char,int,double等元素,那b应该从8的整数倍开始存储。) 原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。 这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。 例1:struct { short a1; short a2; short a3; }A; struct{ long a1; short a2; }B; sizeof(A) = 6; 这个很好理解,三个short都为2。 sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,

stm32中使用#pragma pack(非常有用的字节对齐用法说明)

#pragma pack(4) //按4字节对齐,但实际上由于结构体中单个成员的最大占用字节数为2字节,因此实际还是按2字节对齐 typedef struct { char buf[3];//buf[1]按1字节对齐,buf[2]按1字节对齐,由于buf[3]的下一成员word a是按两字节对齐,因此buf[3]按1字节对齐后,后面只需补一空字节 word a; //#pragma pack(4),取小值为2,按2字节对齐。 }kk; #pragma pack() //取消自定义字节对齐方式 对齐的原则是min(sizeof(word ),4)=2,因此是2字节对齐,而不是我们认为的4字节对齐。 这里有三点很重要: 1.每个成员分别按自己的方式对齐,并能最小化长度 2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度 3.对齐后的结构体整体长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐 补充一下,对于数组,比如: char a[3];这种,它的对齐方式和分别写3个char是一样的.也就是说它还是按1个字节对齐. 如果写: typedef char Array3[3]; Array3这种类型的对齐方式还是按1个字节对齐,而不是按它的长度. 不论类型是什么,对齐的边界一定是1,2,4,8,16,32,64....中的一个. 声明: 整理自网络达人们的帖子,部分参照MSDN。 作用: 指定结构体、联合以及类成员的packing alignment; 语法: #pragma pack( [show] | [push | pop] [, identifier], n ) 说明: 1,pack提供数据声明级别的控制,对定义不起作用; 2,调用pack时不指定参数,n将被设成默认值; 3,一旦改变数据类型的alignment,直接效果就是占用memory的减少,但是performance会下降; 语法具体分析: 1,show:可选参数;显示当前packing aligment的字节数,以warning message的形式被显示; 2,push:可选参数;将当前指定的packing alignment数值进行压栈操作,这里的栈是the internal compiler stack,同时设置当前的packing alignment为n;如果n没有指定,则将当前的packing alignment数值压栈; 3,pop:可选参数;从internal compiler stack中删除最顶端的record;如果没有指定n,则当前栈顶record即为新的packing alignment 数值;如果指定了n,则n将成为新的packing aligment数值;如果指定了identifier,则internal compiler stack中的record都将被pop 直到identifier被找到,然后pop出identitier,同时设置packing alignment数值为当前栈顶的record;如果指定的identifier并不存在于internal compiler stack,则pop操作被忽略; 4,identifier:可选参数;当同push一起使用时,赋予当前被压入栈中的record一个名称;当同pop一起使用时,从internal compiler stack 中pop出所有的record直到identifier被pop出,如果identifier没有被找到,则忽略pop操作; 5,n:可选参数;指定packing的数值,以字节为单位;缺省数值是8,合法的数值分别是1、2、4、8、16。 重要规则: 1,复杂类型中各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个类型的地址相同; 2,每个成员分别对齐,即每个成员按自己的方式对齐,并最小化长度;规则就是每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数中较小的一个对齐; 3,结构体、联合体或者类的数据成员,第一个放在偏移为0的地方;以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度两个中比较小的那个进行;也就是说,当#pragma pack指定的值等于或者超过所有数据成员长度的时候,这个指定值的大小将不产生任何效果; 4,复杂类型(如结构体)整体的对齐是按照结构体中长度最大的数据成员和#pragma pack指定值之间较小的那个值进行;这样当数据成员为复杂类型(如结构体)时,可以最小化长度; 5,复杂类型(如结构体)整体长度的计算必须取所用过的所有对齐参数的整数倍,不够补空字节;也就是取所用过的所有对齐参数中最大的那个值的整数倍,因为对齐参数都是2的n次方;这样在处理数组时可以保证每一项都边界对齐; 对齐的算法:由于各个平台和编译器的不同,现以本人使用的gcc version 3.2.2编译器(32位x86平台)为例子,来讨论编译器对struct 数据结构中的各成员如何进行对齐的。 在相同的对齐方式下,结构体内部数据定义的顺序不同,结构体整体占据内存空间也不同,如下: 设结构体如下定义: struct A { int a; //a的自身对齐值为4,偏移地址为0x00~0x03,a的起始地址0x00满足0x00%4=0;

结构体对齐方式

结构体对齐方式 结构体(struct)的sizeof值,并不是简单的将其中各元素所占字节相加,而是要考虑到存储空间的字节对齐问题。先看下面定义的两个结构体. struct { char a; short b; char c; }S1; struct { char a; char b; short c; }S2; 分别用程序测试得出sizeof(S1)=6 , sizeof(S2)=4 可见,虽然两个结构体所含的元素相同,但因为其中存放的元素类型顺序不一样,所占字节也出现差异。这就是字节对齐原因。通过字节对齐,有助于加快计算机的取数速度,否则就得多花指令周期。 字节对齐原则: 结构体默认的字节对齐一般满足三个准则: 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员自身大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。 通过这三个原则,就不难理解上面两个struct的差异了. 对于struct S1, 为了使short变量满足字节对其准则(2), 即其存储位置相对于结构体首地址的offset是自身大小(short占2个字节)的整数倍,必须在字节a后面填充一个字节以对齐;再由准则(3),为了满足结构体总大小为short大小的整数倍,必须再在c后面填充一个字节。对于struct S2, 却不必如上所述的填充字节,因为其直接顺序存储已经满足对齐准则。 如果将上面两个结构体中的short都改为int(占4个字节), 那么会怎么样呢?程序得出sizeof(S1)=12, sizeof(S2)=8 利用上面的准则,也不难计算得出这样的结果。S1中在a后面填充3个字节、在c后面填充3个字节,这样一共12个字节;S2中在a、b顺序存储之后填充两个字节用以对其,这样一共就8个字节。 当然,在某些时候也可以设置字节对齐方式。这就需要使用 #pragma pack 。 #pragma pack(push) //压栈保存 #pragma pack(1)// 设置1字节对齐 struct { char a; short b; char c; }S1; #pragma pack(pop) // 恢复先前设置 如上所示,将对其方式设为1字节对齐,那么S1就不填充字节,sizeof为各元素所占字节之和即4。这一点在从外部2进制文件中读入struct大小的数据到struct中,是很有用的。 另外,还有如下的一种方式:

C语言结构体(struct)常见使用方法

C语言结构体(struct)常见使用方法 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。 结构体定义: 第一种:只有结构体定义 [cpp]view plain copy 1.struct stuff{ 2.char job[20]; 3.int age; 4.float height; 5.}; 第二种:附加该结构体类型的“结构体变量”的初始化的结构体定义 [cpp]view plain copy 1.//直接带变量名Huqinwei 2.struct stuff{ 3.char job[20]; 4.int age; 5.float height; 6.}Huqinwei; 也许初期看不习惯容易困惑,其实这就相当于: [cpp]view plain copy 1.struct stuff{ 2.char job[20]; 3.int age;

4.float height; 5.}; 6.struct stuff Huqinwei; 第三种:如果该结构体你只用一个变量Huqinwei,而不再需要用 [cpp]view plain copy 1.struct stuff yourname; 去定义第二个变量。 那么,附加变量初始化的结构体定义还可进一步简化出第三种: [cpp]view plain copy 1.struct{ 2.char job[20]; 3.int age; 4.float height; 5.}Huqinwei; 把结构体名称去掉,这样更简洁,不过也不能定义其他同结构体变量了——至少我现在没掌握这种方法。 结构体变量及其内部成员变量的定义及访问: 绕口吧?要分清结构体变量和结构体内部成员变量的概念。 就像刚才的第二种提到的,结构体变量的声明可以用: [cpp]view plain copy 1.struct stuff yourname; 其成员变量的定义可以随声明进行: [cpp]view plain copy 1.struct stuff Huqinwei = {"manager",30,185}; 也可以考虑结构体之间的赋值: [cpp]view plain copy

C语言结构体对齐问题

C语言结构体对齐问题 1。几个结构体例子: struct{ short a1; short a2; short a3; }A; struct{ long a1; short a2; }B; sizeof( A)=6, sizeof( B)=8,为什么? 注:sizeof(short)=2,sizeof(long)=4 因为:“成员对齐有一个重要的条件,即每个成员按自己的方式对齐。其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里默认是8字节)中较小的一个对齐。并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节。”(引用) 结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对齐,则a1,a2,a3都取2字节对齐,则sizeof(A)为6,其也是2的整数倍; B中a1为4字节对齐,a2为2字节对齐,结构体默认对齐参数为8,则a1取4字节对齐,a2取2字节对齐,结构体大小6字节,6不为4的整数倍,补空字节,增到8时,符合所有条件,则sizeof(B)为8; 可以设置成对齐的 #pragma pack(1) #pragma pack(push) #pragma pack(1) struct{

short a1; short a2; short a3; }A; struct{ long a1; short a2; }B; #pragma pack(pop) 结果为sizeof( A)=6,sizeof( B)=6 ************************ #pragma pack(8) struct S1{ char a; long b; }; struct S2 { char c; struct S1 d; long long e; }; #pragma pack() sizeof(S2)结果为24.

C语言内存字节对齐规则20180718

C语言内存字节对齐规则 在C语言面试和考试中经常会遇到内存字节对齐的问题。今天就来对字节对齐的知识进行小结一下。 首先说说为什么要对齐。为了提高效率,计算机从内存中取数据是按照一个固定长度的。以32位机为例,它每次取32个位,也就是4个字节(每字节8个位,计算机基础知识,别说不知道)。字节对齐有什么好处?以int型数据为例,如果它在内存中存放的位置按4字节对齐,也就是说1个int的数据全部落在计算机一次取数的区间内,那么只需要取一次就可以了。如图a-1。如果不对齐,很不巧,这个int数据刚好跨越了取数的边界,这样就需要取两次才能把这个int的数据全部取到,这样效率也就降低了。 图:a-1 图:a-2 内存对齐是会浪费一些空间的。但是这种空间上得浪费却可以减少取数的时间。这是典型的一种以空间换时间的做法。空间与时间孰优孰略这个每个人都有自己的看法,但是C 语言既然采取了这种以空间换时间的策略,就必然有它的道理。况且,在存储器越来越便宜的今天,这一点点的空间上的浪费就不算什么了。 需要说明的是,字节对齐不同的编译器可能会采用不同的优化策略,以下以GCC为例讲解结构体的对齐. 一、原则: 1.结构体内成员按自身按自身长度自对齐。

自身长度,如char=1,short=2,int=4,double=8,。所谓自对齐,指的是该成员的起始位置的内存地址必须是它自身长度的整数倍。如int只能以0,4,8这类的地址开始 2.结构体的总大小为结构体的有效对齐值的整数倍 结构体的有效对齐值的确定: 1)当未明确指定时,以结构体中最长的成员的长度为其有效值 2)当用#pragma pack(n)指定时,以n和结构体中最长的成员的长度中较小者为其值。 3)当用__attribute__ ((__packed__))指定长度时,强制按照此值为结构体的有效对齐值 二、例子 1) struct AA{ //结构体的有效对齐值为其中最大的成员即int的长度4 char a; int b; char c; }aa 结果,sizeof(aa)=12 何解?首先假设结构体内存起始地址为0,那么地址的分布如下 0 a 1 2 3 4 b 5 b 6 b 7 b 8 c 9 10 11 char的字对齐长度为1,所以可以在任何地址开始,但是,int自对齐长度为4,必须以4的倍数地址开始。所以,尽管1-3空着,但b也只能从4开始。再加上c后,整个结构体的总长度为9,结构体的有效对齐值为其中最大的成员即int的长度4,所以,结构体的大小向上扩展到12,即9-11的地址空着。 2) //结构体的有效对齐值为其中最大的成员即int的长度4 struct AA{ char a; char c; int b; }aa sizeof(aa)=8,为什么呢 0 a 1 c

相关文档
最新文档