IA-32运行时环境

来源:互联网 发布:淘宝客在哪里推广 编辑:程序博客网 时间:2024/05/22 04:36
参考链接:http://mentorembedded.github.io/cxx-abi/abi.html#calls

现在来看看实际的运行时环境的实现,如下的PDF中给出了几种CPU的函数调用规范,我们现在只对ia-32进行分析
其中linkage area存放caller的下一条指令的地址
saved frame pointer:caller的stack frame的地址
saved register:存放函数调用后必须回复的寄存器的内容
local storage:存放callee的局部变量
其中parameter area是caller负责的,它需要把参数push到栈中,然后调用callee,调用操作会把caller的下一条指令push到栈中,也就是linkage area的内容,之后pc会跳转到callee的代码段,后面的内容就需要callee完成了
可以通过stack frame的正偏移和负偏移来判断是caller部分还是callee部分

callee至少需要完成两个过程:
Prologs:
1.push ebp(ebp就是frame pointer)
2.esp赋值给ebp
3.把必须preserved的register入栈,如ESI,EDI,EBX
4.在栈中为local storage分配空间
Epilogs:
1.释放栈中为local storage分配的空间
2.恢复preserved reigister(ESI,EDI,EBX,EBP)
3.把linkage的值赋值给pc

参数传递规则
1.栈必须是16字节对齐的,对于非vector的参数必须是4字节对齐的,所以对于单字节和双字节的参数,会被扩展为4字节,称为promotion
2.关于入栈的顺序,是从右到左入栈的
例子:
void foo(SInt32 i, float f, double d, SInt16 s, UInt8 c);
Figure 2  Argument assignment with arguments of the fundamental data types
从这里可以看到在入站之前,首先进行的就是16字节对齐的操作,之后是data type promotion

返回结果规则:
返回标量值
1.如果只返回一个整数或者指针,使用EAX寄存器
2.如果返回浮点数,使用STO寄存器
3.调用者使用完后,需要删除寄存器中的值
返回structure
1.如果structure的大小是1或者2个字节,那么使用EAX
2.如果structure的大小是4或者8个字节,那么使用EAX和EDX
3.如果大于8字节,那么会在callee中添加一个指针参数用来传递返回值,例子如下:
typedef struct {
    float ary[8];
} big_struct;
void callee(big_struct *p, int a, float b)
{
    big_struct callee_struct;
    ...
    *p = callee_struct;
    return;
}
caller() {
    big_struct caller_struct;
    callee(&caller_struct, 3, 42.0);
}
Preserved Register:

Type

Name

Preserved

Notes

General-purpose register

EAX

No

Used to return integral and pointer values. The caller may also place the address to storage where the callee places its return value in this register.

 

EDX

No

Dividend register (divide operation). Available for general use for all other operations.

 

ECX

No

Count register (shift and string operations). Available for general use for all other operations.

 

EBX

Yes

Position-independent code base register. Available for general use in non–position-independent code.

 

EBP

Yes

Stack frame pointer. Optionally holds the base address of the current stack frame. A routine’s parameters reside in the previous frame as positive offsets of this register’s value. Local variables reside at negative offsets.

 

ESI

Yes

Available for general use.

 

EDI

Yes

Available for general use.

Stack-pointer register

ESP

Yes

Holds the address of the bottom of the stack.



0 0
原创粉丝点击