标签:
1.实时系统概念
2.编译连接
3.AT&T汇编指令学习(GCC)
4.内存对齐
5.Big-Endian大端模式和Little-Endian小端模式
6.过程调用
后台是各种面向硬件的程序,如中断,定时器,gpio等。
前台是:
main()
{
while(1)
{
;
}
}
循环中不断调用各种函数实现功能。
指处理时不可分割的代码,一旦这部分代码运行就不可以打断、
为了确保代码能正常运行,进入临界段代码钱需要关中断,执行完后再开中断。
一个任务也就是一个线程,是一个简单的程序。
任务间通信最简单的办法是使用数据共享结构。
任务间通信途径:1)全局变量;2)发消息给另一个任务。
任务切换(context switch)
不可剥夺型内核,允许使用不可重入函数。
可剥夺型内核,,最高优先级的任务一就绪,总能得到CPU的使用权。,不能直接使用不可重入函数。
处理共享数据时保证互斥,最简单的办法是关中断和开中断。
一种约定机制。
就好像一把钥匙。任务要运行下去需要获得信号量,且信号量没有被占用。
两个任务相互等待对方释放资源。
一个中断或者任务触发另一个任务。
一种内存共享方式。
特定的周期性中断,如同系统的心脏。
可重定位文件:
包含代码和数据
可被用来链接成执行文件或者共享目标文件
linux(.o) windows(.obj)
可执行文件:
包含可以执行的程序
系统可以直接执行的文件
linux (ELF文件,无后缀) windows (.exe)
共享目标文件:
包含代码和数据
跟可重定位文件和共享目标文件链接,产生新的目标文件
动态连接器将共享目标文件与可执行文件结合,作为进程映像的一部分来运行
linux(.so) windows (.DLL)
核心转储文件
Linux(core dump)
目标文件的具体内容
file header
目标文件头
code section
程序指令(.code /.text)
存放程序代码程序
data section
程序数据(.data /.bss)
.data段 初始化的全局和局部静态变量
.bss段 未初始化的全局和局部静态变量
.bss(block started by symbol)符号预留块,没有内容不占据空间
othe section
还有可能包含的其他段,例 bank data .ect
程序指令和数据分开存放的优点?3点。
操作码命令格式:
源/目的操作数顺序:
Intel语法格式中命令表示格式为:”opcode dest, src”; “操作码 目标, 源”
AT&T语法格式表示为:”opcode src, dest”; “操作码 源, 目标”
操作数长度标识:
在AT&T语法中,通过在指令后添加后缀来指明该指令运算对象的尺寸.
后缀 ‘b’ 指明运算对象是一个字节(byte)
后缀 ‘w’ 指明运算对象是一个字(word)
后缀 ‘l’ 指明运算对象是一个双字(long)
Intel语法中指令’mov’在AT&T语法必须根据运算对象的实际情况写成:’movb’,’movw’或’movl’。
注:若在AT&T中省略这些后缀,GAS将通过使用的寄存器大小来猜测指令的操作数长度.
SECTION:[BASE + INDEX*SCALE + DISP];
段:[基地址+变址*比例因子+偏移量] SECTION:DISP(BASE, INDEX, SCALE);
段:偏移量(基地址,变址,比例因子) asm("statements");
asm ( "statements" : output_regs : input_regs : clobbered_regs);
条件码寄存器(单个bit):
cf(进位标志),zf(零标志),sf(符号标志),of(溢出标志)…
访问条件码指令:cmp,test,set…
t = a + b;
cf: (unsigned) t < (unsigned) a;//无符号溢出
zf: t == 0;//零
sf: t < 0;//负数
of: (a < 0 == b < 0) && (t < 0 != a < 0)//有符号溢出
内存对齐的规则
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。
比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。某些处理器在数据不满足对齐要求的情况下可能会出错.
但是Intel的IA32架构的处理器则不管数据是否对齐都能正确工作。不过Intel奉劝大家,如果想提升性能,那么所有的程序数据都应该尽可能地对齐。
定义
- Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
- Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
- 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序.
- 高/低字节定义:在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78.
例子分析:
unsigned int value = 0x12345678
1.Big-Endian: 低地址存放高位
|
||
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.Little-Endian: 低地址存放低位
|
||
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)
内存地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
---|---|---|---|---|
存放内容 | 0x78 | 0x56 | 0x34 | 0x12 |
在Big- endian模式CPU内存中的存放方式则为
内存地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
---|---|---|---|---|
存放内容 | 0x12 | 0x34 | 0x56 | 0x78 |
注意:通常我们说的主机序(Host Order)就是遵循Little-Endian规则。所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序 (Little-Endian)和网络序(Big-Endian)的转换。
检查CPU是大端还是小端:
int checkCPU(void)
{
union
{
int a;
char b;
}c;
c.a = 1;
return (c.b == 1);
}
说明:
返回值在相对%ebp偏移量为4的位置;
第一个参数放在相对于%ebp偏移量为8的位置;
支持过程调用和返回的指令:
一个过程调用的整个汇编流程示意:
标签:
原文地址:http://blog.csdn.net/yang_hong_/article/details/51700135