IA-32运行时环境

本文详细介绍了IA-32架构下的运行时环境,包括函数调用规范、参数传递、返回结果规则以及函数调用过程中的帧指针操作。在IA-32中,caller需将参数压栈并保存返回地址,callee则负责保存和恢复特定寄存器、分配局部变量空间。参数传递遵循从右到左的顺序,并进行对齐处理。返回值通常存储在EAX或STO寄存器中,结构体返回值可能涉及额外的指针参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


现在来看看实际的运行时环境的实现,如下的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.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值