C如何减小程序大小

时间:2018-06-22 09:28:09

标签: c code-size

我正在为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函数,例如:

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个字符+空值。但是程序内存也增加了3。我尝试了不同的字符串长度,但程序内存却继续增加了3个字节。

我该如何解决这个问题?

添加: 我正在使用Keil的C编译器,我对程序的大小很满意。 uController是具有仿真80C51芯片的FPGA芯片。对于此虚拟80c51,我正在编写代码。我的主程序有32kb的内存,变量有32kb的

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

2 个答案:

答案 0 :(得分:0)

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

#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

答案 1 :(得分:0)

  

char xdata * msg1 =“ Hello World”;

     

char xdata msg1 [] =“ Hello World”;

我认为您永远不能以这种方式缩短程序,因为即使从xdata访问 消息,C运行时也会首先将其复制到那里,并来自代码(初始化数据)。

如果确实有很多“ print()”,则可以通过声明其参数的正确指针类型来压缩一些字节。我要解释一下:由于8051的体系结构很奇怪,“高级” C“通用”指针需要三个字节-两个字节作为偏移量,以及第三个字节来指定它是指向XDATA还是指向CODE。然后,每次调用print()都必须构造一个指针。

例如,如果您声明:

  

无效打印(char xdata * x)

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

您的大多数文本似乎都是常量,因此它们将在代码中;因此您需要的指针类型是不是XDATA而是CODE(或其他正确的关键字)

一旦您像上面那样声明了print(),您将再也不能打印不在代码段中的数据了;也许您将需要另一个功能,例如

  

printx(char *什么)

它将像以前一样接受任何段中的char *,但是只有在需要时才调用此昂贵的printx()。

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

附录:______________

发生一次我几乎没有文本的余地。通过应用一些文本压缩,我很好地解决了问题。鉴于所有文本均为纯ASCII,我使用了127个以上的字符来指向文本中常见的重复单词。例如,如果字符串“ Hello”重复几次,则可以用0x80 " world"替换“ Hello world”。当然,打印例程必须检测这些特殊标记并管理减压-但这很容易。