离开以后 » 日志 » SystemV ABI笔记(Intel386处理器,第4版)
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个参数。
函数要把返回值复制到地址所指向的对象中。
函数必须在它返回时把这个地址从栈中移出。意即虽然这个地址是由调用者压入堆栈的,但它却是由被调用者清除的。
在结构或联合中,每个成员变量的首地址要与它对应类型的对齐方式相匹配。在
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个参数。
函数要把返回值复制到地址所指向的对象中。
函数必须在它返回时把这个地址从栈中移出。意即虽然这个地址是由调用者压入堆栈的,但它却是由被调用者清除的。
相关日志:
- » 不敢分享……
- » 编译原理卷子好变态啊!!!!
- » 革新自己的语言和思维
- » 几个正则表达式
收藏:
QQ书签
del.icio.us
订阅:
Google
抓虾
