文章目錄
  1. 1. 一、C51专用编译选项
    1. 1.1. 1.1 C标准
    2. 1.2. 1.2 芯片系列
    3. 1.3. 1.3 存储模式
    4. 1.4. 1.4 堆栈
    5. 1.5. 1.5 size检查
    6. 1.6. 1.6 寄存器优化开关
    7. 1.7. 1.7 汇编优化
  2. 2. 总结

一、C51专用编译选项

1.1 C标准

sdcc提供c89 c99 c11的三种标准,编译选项分别是

1
2
3
4
--std-c89
--std-c99
--std-c11
--std-sdcc99

据说用c99,如果函数没有形参编译就不能通过,不能默认为void。在写for函数的时候,不能在第一分句里申明变量,必须提前申明。—std-sdcc99是默认的编译选项,在使用c99规范的时候,兼容c89规范,真方便。

anyway,我觉得很少有人会使用这个编译选项。

1.2 芯片系列

sdcc提供很多种芯片系列的选择,粗略看了一下有pic16bit,飞思卡尔,z80等等。如果是51系列的话,编译选项是-mmcs51

1
-mmcs51

1.3 存储模式

ssdc提供的memory model选项有这么几个

1
2
3
4
--model-small
--model-medium
--model-large
--model-huge

small模式,对应keil的SMALL模式,变量默认存在internal ram中,该模式需要变量总占用的空间小于256bit。

medium模式,对应keil的COMPACT模式,变量默认存在external ram中。需要注意的是,有些51单片机本身就有内部的扩展ram,为了与旧单片机相兼容,这些内部扩展ram在名义上也算是一种外部ram。

large和huge模式是一样的,变量也存在external ram中,不同的是,它可以切换bank。由于c51的最大寻址范围也就是FFFFH,即64K。所以如果要扩展64K以上的ram只能用bank切换的办法。bank切换办法是用一个特殊寄存器来切换bank,将LSB存在r0,MSB存在r1,bank号存在r2。然后用 __sdcc_banked_call来调用位于其他bank的函数,再用__sdcc_banked_ret返回当前函数。

1.4 堆栈

1
--xstack

可以用xstack选项指定external ram的一段空间作为栈区(通常是前256个字节),这样所有的可重入函数的变量和参数传递都会用堆栈来实现。通常默认的栈空间是在internal ram的后区。

1.5 size检查

sdcc提供一些size选项来检查存储控件的使用情况

1
2
3
4
--iram-size <Value>
--xram-size <Value>
--code-size <Value>
--stack-size <Value>

iram-size 用来检查片内ram的使用情况
xram-size 用来检查外部ram的使用情况
code-size 用来检查rom的使用情况
stack-size 用来检查堆栈的使用情况

1.6 寄存器优化开关

1
2
--pack-iram
--no-pack-iram

—pack-iram是默认选项,意思是将多余的寄存器用来存放变量,以加快运行速度。因为这是一种通俗的做法,所以—no-pack-iram选项几乎很少使用,编译器的作者说下一版将移除这个选项。如果想不让编译器优化某个变量的访问,直接使用volatile关键字就可以了。假如担心一个全局变量会被中断程序或者其他线程修改,那么声明它为volatile就可以了,编译器会让该变量在每次访问时都重新从内存读取。

1.7 汇编优化

1
--acall-ajmp

—acall-ajmp选项用来将3字节的汇编指令lcall/ljpm替换成2字节的指令acall-ajmp,这就要求代码总占用空间限制在2K以内。

我很好奇这个选项的使用场景,于是在github上搜索了一下,发现它通常用于一些微型的bootloader。

1
--no-ret-without-call

—no-ret-without-call 用于xc800系列的单片机,用于保持堆栈平衡。

总结

  • sdcc用-mmcs51来指定单片机为51系列
  • sdcc有与keil相同的memory model
  • 可以用编译选项告诉编译器程序使用外部ram里的堆栈
  • 可以用编译选项检查各存储空间的占用情况
文章目錄
  1. 1. 一、C51专用编译选项
    1. 1.1. 1.1 C标准
    2. 1.2. 1.2 芯片系列
    3. 1.3. 1.3 存储模式
    4. 1.4. 1.4 堆栈
    5. 1.5. 1.5 size检查
    6. 1.6. 1.6 寄存器优化开关
    7. 1.7. 1.7 汇编优化
  2. 2. 总结