1

我正在为 uController 编写 ac 程序,我设法用代码填充了 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 是一个 FPGA 芯片,具有仿真的 80C51 芯片。对于这个虚拟 80c51,我正在编写代码。我有 32kb 内存用于主程序,32kb 用于变量

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

4

2 回答 2

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

于 2018-06-22T14:21:43.170 回答
0

char xdata *msg1 = "你好世界";

char xdata msg1[] = "你好世界";

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

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

例如,如果您声明:

无效打印(字符 xdata *x)

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

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

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

printx(char* 什么)

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

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

附录:______________

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

于 2018-06-25T08:14:27.937 回答