SystemV ABI笔记(Intel386处理器,第4版)

yayj 发表于 2005-10-29 20:37:36

1. 字节对齐
在结构或联合中,每个成员变量的首地址要与它对应类型的对齐方式相匹配。在

struct {

char c;

short s;

};

这个结构中c和s成员之间就有1个字节的填充区,sizeof的运算结果是4。

结构或联合的对齐字节数是等于成员变量中对齐字节数最大的一个。

union {

char c[3];

short s;

};

这个联合的对齐字节数应该是与short类型一样,sizeof的运算结果是4。

未显式声明为signed的bit域都认为是无符号的,如有char c:3,则cÎ[0,3]。

bit域必须放在它对应类型的字段内,并且这个字段必须是对齐的。在

struct {

short t:9;

short u:9;

};

这个结构中,t和u之间有7bit的填充区。而在

struct {

short s:9;

int i:9;

};

这个结构中,s和i之间就没有填充区。

未命名的bit域不会影响整个结构或联合的对齐字节数,但会影响成员的对齐。
2. 函数调用

栈是按字长(对Intel386来说是4字节)对齐的。参数入栈的时候也要保持栈的对齐,若参数的长度不足4字节或4字节的倍数,则需要在参数的后面添加填充区。

若函数使用了%ebp、%ebx、%edi、%esi和%esp这几个寄存器,则需要把它们保存在自己的栈帧(Stack Frame)后。

几个主要寄存器的意义:

%esp:栈顶指针,它始终指向当前栈顶,并且始终按字长对齐。

%ebp:栈帧指针(stack frame pointer),栈帧是可选的,gcc中可以用-fomit-frame-pointer取消栈帧。

%eax:若函数的返回值是整数(包括char、short等)或者指针时,函数一般用它来保存返回值。若返回值是一个结构或联合,函数会用它来保存结构或联合的地址(可能有编译器优化的问题)。其它时候%eax是可以任意读写的。

%ebx:当把程序编译为与位置无关的代码时,%ebx用来保存全局偏移表的地址;其它时候它只是用来作为函数的局部寄存器。

被调用的函数必须从堆栈中移出返回地址,让%esp恢复到call指令调用前的状态。意即入栈的参数是由调用者来清理的。

关于返回结构或联合的函数。

这个函数的调用者要在自己的栈中为这个返回值预留出空间,并在把所有参数压入堆栈后,再把这个空间的地址压入堆栈,相当于第0个参数。

函数要把返回值复制到地址所指向的对象中。

函数必须在它返回时把这个地址从栈中移出。意即虽然这个地址是由调用者压入堆栈的,但它却是由被调用者清除的。
关键词(Tag): 编译原理 abi 人模狗样


收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定