ZHCADC5A June 2013 – June 2020
对于 MSP430 和 MSP430X,大小大于 32 位且最多 64 位的实参使用四倍字寄存器。例如,R8::R11 是本手册中使用的表示法,表示由寄存器 R8、R9、R10 和 R11 依次组成的四倍字寄存器。编号最低的寄存器保存 LSW。四倍字寄存器必须对齐。因此,只有 R8::R11 和 R12::R15 是有效的四倍字寄存器。四倍字寄存器需要特殊处理。
如果剩余足够的实参寄存器(全部四个)来传递 64 位值,则将使用全部四个实参寄存器。否则,64 位值将完全在栈上传递。这可能会留下未使用的实参寄存器(也就是“空洞”)。调用约定将尝试用后续实参回填此空洞,但前提是这些后续实参完全适合寄存器(请参阅下面的示例 2)。也就是说,在任何实参被置于栈上之后,没有任何实参将被置于“拆分对“中,如节 3.3.3所述。
MSP430 和 MSP430X 示例 1:
C 源代码
void func1(long long a0, long long a1);
long long a0, a1;
func2(void)
{
func1(a0, a1);
}
在任何模型中编译:
SUB.W #8,SP
MOV.W &a0+0,R12
MOV.W &a0+2,R13
MOV.W &a0+4,R14
MOV.W &a0+6,R15
MOV.W &a1+0,0(SP)
MOV.W &a1+2,2(SP)
MOV.W &a1+4,4(SP)
MOV.W &a1+6,6(SP)
MSP430 和 MSP430X 示例 2:
此示例显示了一个不完全适合寄存器的 64 位实参,因此它完全在栈上传递,留下未使用的寄存器,然后用实参 a2、a3 和 a4 回填这些寄存器。
C 源代码
void func1(int a0, long long a1, int a2, int a3, int a4);
int a0, a2, a3, a4;
long long a1;
func2(void)
{
func1(a0, a1, a2, a3, a4);
}
在任何模型中编译:
SUB.W #8,SP
MOV.W &a0,R12
MOV.W &a1+0,0(SP)
MOV.W &a1+2,2(SP)
MOV.W &a1+4,4(SP)
MOV.W &a1+6,6(SP)
MOV.W &a2,R13
MOV.W &a3,R14
MOV.W &a4,R15
MSP430 和 MSP430X 示例 3:
此示例显示了一个不完全适合寄存器的 64 位实参,因此它完全在栈上传递,留下未使用的寄存器,然后将其回填。不过,最后一个实参(32 位类型)不完全适合寄存器,因此它完全在栈上传递。如果 64 位实参未在栈上,则此类型将拆分,一部分在 R15 中传递,一部分在栈上传递。
C 源代码
void func1(int a0, long long a1, long a2, long a3);
int a0;
long long a1;
long a2, a3;
func2(void)
{
func1(a0, a1, a2, a3);
}
在任何模型中编译(注意 R15 未使用):
SUB.W #12,SP
MOV.W &a0,R12
MOV.W &a1+0,0(SP)
MOV.W &a1+2,2(SP)
MOV.W &a1+4,4(SP)
MOV.W &a1+6,6(SP)
MOV.W &a2+0,R13
MOV.W &a2+2,R14
MOV.W &a3+0,8(SP)
MOV.W &a3+2,10(SP)
在 MSP430 和 MSP430X 上,仅当使用四倍字寄存器时才会发生空洞和回填。如果仅使用单个寄存器和寄存器对,实参寄存器按顺序使用,则不会发生回填和空洞。