C 如何减小程序大小



我正在为uController编写一个c程序,我设法用代码填充了32kb。

该程序已满,具有以下"打印"功能:

void print(char *x)
{
while(*x) {
SerialWrite(*x++);}
}

SerialWrite 看起来像:

void SerialWrite(unsigned char c)
{
while(tx_buffer_size>250);
ES=0;
tx_buffer_size++;
if (tx_buffer_empty == 0){
txBuffer[tx_in++] = c;}
else {
tx_buffer_empty = 0;
SBUF = c;}
ES=1;
} 

我用字符串文本作为参数调用打印函数,如下所示:

print("Hello World");

我只使用了32kb外部存储器中的2.2kb,所以我的结论是将"Hello World"移到外部存储器,而不是在主程序中对其进行硬编码。

不幸的是,我的尝试实际上使情况变得更糟,我做了以下工作:

char xdata *msg1 = "Hello World"; // <-- this made it worse, and the external memory space was not used at all
print(msg1);

比我尝试:

char xdata msg1[] = "Hello World";
print(msg1);

这确实将外部存储器大小增加了 12,这是正确的,因为字符串包含 11 个字符 + null。但程序内存也增加了3。我尝试了不同的字符串长度,但程序内存不断增加 3 个字节。

如何解决这个问题?

加法: 我正在使用Keil的C编译器,并且我倾向于程序大小进行编译。 uController是一个FPGA芯片,具有模拟的80C51芯片。对于这个虚拟 80c51,我正在编写代码。我有 32kb 内存用于主程序和 32kb 内存用于变量

编辑:*msg[]是一个错字,它必须是*msg

char xdata *msg1 = "Hello World";

char xdata msg1[] = "Hello World";

我认为你不能以这种方式缩短你的程序,因为即使消息将从xdata 访问,它也会首先由 C 运行时复制到那里,从代码(初始化数据(中获取它。

如果你真的有很多"print((",那么你可以通过为其参数声明正确的指针类型来挤压一些字节。我解释说:由于 8051 的奇怪架构,"高级"C "通用"指针需要三个字节 - 两个字节作为偏移量,第三个字节用于指定它是指向 XDATA 还是代码。然后每次调用 print(( 都必须构造这样一个指针。

例如,如果您声明:

无效打印(char xdata *x(

现在 print(( 只接受指向 Xdata 的指针,并且只需要两个字节长的指针。每次调用 print(( 都会更简单。

似乎你的大部分文本都是恒定的,所以它们将在代码中;所以你需要的指针类型不是XDATA,而是CODE(或者其他关键字是正确的(。

一旦你像上面这样声明了print((,你就不能再打印不在代码段中的数据;也许你需要另一个函数,比如

printx(char* what(

它将像以前一样接受来自任何段的 char*,但您只会在需要时调用这个昂贵的 printx((。

希望这有帮助;8051非常奇特,它的编译器很复杂(但Keil很棒(。我建议看看生成的(低级(代码,也许你可以发现一些其他的内存浪费。祝你好运!

补遗:______________

我曾经遇到过一次,几乎没有文本的空间。我通过应用一些文本压缩很好地解决了。鉴于所有文本都是纯ASCII,我使用了超过127个字符的字符来指出文本中常见的重复单词。例如,如果字符串"Hello"重复几次,则可以将"Hello world"替换为0x80 " world"。当然,打印例程必须检测这些特殊标记并管理减压 - 但这非常容易。

简而言之,将这一行放在源文件的开头:

#pragma STRING (XDATA)

这些页面可以帮助您更好地理解:

http://www.keil.com/support/man/docs/c51/c51_le_const.htm http://www.keil.com/support/man/docs/c51/c51_string.htm

2018/06/25 编辑: 试试这一行:

#pragma O2 STRING (XDATA)

如上面的第二个链接和本页所述,应启用 OMF2 以使用 STRING 指令 http://www.keil.com/support/man/docs/c51/c51_omf2.htm

最新更新