我可以将返回数据类型从int修改为int8_t或int16_t吗?

时间:2015-10-30 11:36:05

标签: c

我正在使用MIPS32并在C中编码。

目前我的代码中的许多函数返回' int'数据类型。

由于我的开发是在资源受限的硬件上(甚至是字节很重要),并且返回值只是错误代码(不要超过255),我打算将返回类型缩小为int8_t或int16_t。

我想要实现的是减少调用者的堆栈/内存使用量。

在我尝试之前, 这会导致调用者的堆栈/内存使用量减少吗?或

因为我听说过内存对齐(大多数是4个字节)&不太了解,这会在这里发挥一项糟糕的运动吗?

实施例

int caller(){
    int8_t status;
    status = callee();

}

int8_t callee() {
    ...
    return -1;
}

在上面的示例中,status标识符声明为int8_tint16_tint是否与mips32有关?

3 个答案:

答案 0 :(得分:2)

当涉及到调用堆栈时,这将完全没有变化,可以在此处找到MIPS调用堆栈的示例。 https://courses.cs.washington.edu/courses/cse410/09sp/examples/MIPSCallingConventionsSummary.pdf

  

$ 31   $ RA   该   退货地址    在子程序调用中。

下面是一个图像,你会看到一个完整的寄存器的返回地址,在你使用32位机器的情况下,你的寄存器大小为32位,并没有改变。

我不得不问,你在做什么需要MIPS?一般来说,这是一种用于教学目的的语言,并没有太多的现实世界实际用途,因为它有许多缺陷。作为一个例子,这个返回地址的概念在X86等现代程序集中不存在,其中堆栈指针将包含所有信息。

编辑: 正如下面的人所指出的,我有点不公平。从技术上讲,这些地址也存在。

  

$ 2- $ 3 $ v0- $ v1这些寄存器包含   回归价值    一个子程序;如果   值只有1个字,$ v0很重要。

虽然他们有一个集合大小,但从调用堆栈的角度来看,他们使用的是一个完整的寄存器。从理论上讲,我相信MIPS有办法在一个寄存器中存储4个字节,但我不确定。更重要的是,尽管使用MIPS的工作方式,但只有在调用深度为一个函数时才能使用这些返回寄存器。如果你在一个函数中调用一个函数,那么这个概念就会崩溃,并且返回地址变得必需,因此为什么我只是原始地展示了一个。

答案 1 :(得分:0)

首先,“不超过255”表示您应该使用uint而不是int

手动优化代码大小时,您应该使用uint_leastn_t类型。这些类型允许编译器选择代码工作所需的最小可能类型,其宽度至少为n个字节。

在您的情况下,这将是uint_least8_t。当然,如果编译器总是选择32位类型,因为这是对齐访问所需要的,那么通过替换int获得的唯一东西就是更好的可移植性。

答案 2 :(得分:0)

在MIPS32上,前四个函数参数(整数或指针;为简单起见,我不考虑64位整数,浮点数或结构)到达寄存器a0到a3。其余的进入堆栈,堆栈内存的每个机器字只保存一个参数。因此,就传递错误代码而言,没有区别。

如果必须将错误代码存储在本地(自动)变量中,很多将取决于代码。但是,MIPS有很多寄存器,并且有可能存在可用于错误代码的寄存器,因此不需要堆栈空间。

如果你有全局变量持有错误代码,那么使用不同大小的类型肯定会有区别。

回到堆栈,您应该注意到还有其他一些事情在发挥作用......

首先,堆栈必须对齐。由于现代编译器倾向于将堆栈指针对准不在机器字的多个上,而是在两个机器字的多个上,因此这更加恶化。因此,如果您只考虑一个错误代码,那么编译器填充堆栈上的局部变量以使其累积大小为两个机器字的倍数,很可能会取消任何增益。 / p>

其次,堆栈指针通常在函数入口处仅递减一次本地和临时变量的大小(并且在退出时仅反转一次)。这意味着在函数的某些位置可能存在一些未使用的堆栈空间,这些空间仅保留用于函数的其他位置。因此,函数某些地方的调用(特别是深度递归调用)会过度浪费堆栈空间。

第三,ABI要求到达a0到a3的那四个参数具有与它们相关联的堆栈存储器,因此它们可以存储在那里并通过printf等函数中的指针进行寻址(回忆stdarg.h' s va_list,va_start(),va_arg()等)。因此,许多调用也可能浪费那16个字节的堆栈空间。

您可能想要考虑的另一件事是,当函数返回8位或16位整数类型时,调用者需要将这些8/16位符号扩展(或零扩展)到整个机器字大小(32位),这意味着调用者将不得不使用其他指令,如seb,seh和andi。因此,这些可能会对代码大小产生负面影响。

最终,它在很大程度上取决于您的代码和编译器。您可以使用两种类型测量堆栈使用情况,并使用编译器的不同优化选项并选择最佳选项。您还可以尝试重构代码以避免调用或使编译器更容易对其进行优化(例如,静态函数有助于编译器在调用它们时可能偏离ABI并更有效地优化它们并传递和返回值和从他们)。这就是你应该做的,尝试不同的事情,并选择你最喜欢的。