写在前面
就我所知,STM8的开发平台有两种:意法官方的STVD和IAR for STM8. STVD没尝试过。反正IAR用的感觉还凑合,各种该有的功能都有,但界面不怎么友好。估计是低版本的缘故,由于我长时间盯着屏幕眼睛酸痛,所以没办法只能把编辑界面底色改成黑色,可TM怎么行号编程白色的了?根本看不清。看不清就不看了呗,反正也没啥用。但是就是感觉超不爽。而且字体显示不知道怎么搞的,在缩放的时候就变得特别奇怪,跟手写的一样。
相关资料
如之前所述,官方的永远是最好的,没有谁比创造者更了解他的产品了。
环境设置
俗话说,站在巨人的肩膀上能看得更远。学习汇编也是一样,先看代码。但是由于汇编对于不同的芯片差异很大,网络上也很难找到资源。怎么办呢?最好的办法是去看看编译环境是怎么把c语言转换成汇编的。但是默认情况下,编译结果是不会自动跑到workspace的。所以需要作如下设置:
1. workspace右键选’options…'或单击Project菜单选择’options…'打开工程选项
2. 选择 ‘C/C++ Compiler’,在 ‘List’ 选项卡中选择 ‘Output assembler file’,并选择其子选项 'Include source’
Output assembler file’ 是为了让编译器输出汇编的编译结果,‘Include source’ 可以把对应的C语言标在每段汇编前,这样有助于理解每段汇编的含义。如果想看到全部汇编信息,请将 ‘Include all call frame information’ 勾选。
3. 还是在 ‘Options…’ => ‘C/C++ Compiler’ 中,选择 ‘Optimization’ 选项卡,优化等级选择 ‘Low’ 或 'None’
选择优化等级的原因是,在高等级的优化中,C语言和汇编的对应关系不是特别明显,有的时候会把十几行代码一起优化掉,虽然结果相同,但是你很难去用自己写的时候的思路去理解生成的代码,而且有的时候会把你的代码逻辑彻底变掉。之前就遇到过这种情况,初始化的时候本来想用查表法去对参数赋初值,结果发现改Flash里面的数据根本不会影响运行结果。把汇编打开之后,发现居然把从Flash取值的指令直接优化成立即数寻址。唉,不得不感慨编译器不懂我啊。当然还有其他更好的办法解决,之后会讲到。
完成以上设置之后,去编译你的工程,你会发现在每个c文件下多了个Output文件夹,点开后,里面有一个 ‘.s’ 文件,这个里面就是编译得到的汇编结果。
汇编语言结构
做完上述设置之后,编译完打开 ‘.s’ 文件,你会看到如下格式的代码:
RTMODEL "__SystemLibrary", "DLib"
RTMODEL "__code_model", "small"
RTMODEL "__core", "stm8"
RTMODEL "__data_model", "medium"
RTMODEL "__rt_version", "4"
EXTERN ?b0
EXTERN ?b1
EXTERN ?w0
EXTERN ?w1
PUBLIC array
PUBLIC main
PUBLIC val
CFI Names cfiNames0
CFI StackFrame CFA SP DATA
CFI Resource A:8, XL:8, XH:8, YL:8, YH:8, SP:16, CC:8, PC:24, PCL:8
CFI Resource PCH:8, PCE:8, ?b0:8, ?b1:8, ?b2:8, ?b3:8, ?b4:8, ?b5:8
CFI Resource ?b6:8, ?b7:8, ?b8:8, ?b9:8, ?b10:8, ?b11:8, ?b12:8, ?b13:8
CFI Resource ?b14:8, ?b15:8
CFI ResourceParts PC PCE, PCH, PCL
CFI EndNames cfiNames0
CFI Common cfiCommon0 Using cfiNames0
CFI CodeAlign 1
CFI DataAlign 1
CFI ReturnAddress PC CODE
CFI CFA SP+2
CFI A Undefined
CFI XL Undefined
CFI XH Undefined
CFI YL Undefined
CFI YH Undefined
CFI CC Undefined
CFI PC Concat
CFI PCL Frame(CFA, 0)
CFI PCH Frame(CFA, -1)
CFI PCE SameValue
CFI ?b0 Undefined
CFI ?b1 Undefined
CFI ?b2 Undefined
CFI ?b3 Undefined
CFI ?b4 Undefined
CFI ?b5 Undefined
CFI ?b6 Undefined
CFI ?b7 Undefined
CFI ?b8 SameValue
CFI ?b9 SameValue
CFI ?b10 SameValue
CFI ?b11 SameValue
CFI ?b12 SameValue
CFI ?b13 SameValue
CFI ?b14 SameValue
CFI ?b15 SameValue
CFI EndCommon cfiCommon0
// E:socexample_emptymain.c
// 1 #include "Untitled1.h"
// 2 typedef enum {FALSE = 0, TRUE = !FALSE} bool;
SECTION `.near.bss`:DATA:REORDER:NOROOT(0)
// 3 int val;
val:
DS8 2
SECTION `.near.data`:DATA:REORDER:NOROOT(0)
// 4 int array[10] = {1,33,2,6,8,9,4,45,8,0};
array:
DC16 1, 33, 2, 6, 8, 9, 4, 45, 8, 0
SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
CFI Block cfiBlock0 Using cfiCommon0
CFI Function main
CODE
// 5 int main( void )
// 6 {
// 7 int i = 0;
main:
CLR S:?b1
CLR S:?b0
// 8 int buf;
// 9 bool flag = TRUE;
LD A, #0x1
JRA L:??main_0
// 10 while(1)
// 11 {
// 12 if(array[i] > array[i+1])
// 13 {
// 14 buf = array[i];
// 15 array[i] = array[i+1];
// 16 array[i+1] = buf;
// 17 flag = FALSE;
// 18 }
// 19 if(i == 9)
// 20 {
// 21 if(flag)
// 22 {
// 23 break;
// 24 }
// 25 i = 0;
??main_1:
CLR S:?b1
CLR S:?b0
??main_0:
LDW X, S:?w0
SLLW X
ADDW X, #array + 2
LDW X, (X)
LDW S:?w1, X
LDW X, S:?w0
SLLW X
ADDW X, #array
LDW Y, X
LDW X, S:?w1
CPW X, (Y)
JRSGE L:??main_2
LDW X, S:?w0
SLLW X
LDW X, (L:array,X)
LDW S:?w1, X
LDW X, S:?w0
SLLW X
ADDW X, #array + 2
LDW X, (X)
LDW Y, X
LDW X, S:?w0
SLLW X
LDW (L:array,X), Y
LDW X, S:?w0
SLLW X
LDW Y, S:?w1
ADDW X, #array + 2
LDW (X), Y
SUBW X, #array + 2
CLR A
main_2:
LDW X, S:?w0
CPW X, #0x9
JRNE L:??main_0
TNZ A
JREQ L:??main_1
// 26 }
// 27
// 28 }
// 29 return 0;
CLRW X
RET
// 30 }
CFI EndBlock cfiBlock0
SECTION VREGS:DATA:REORDER:NOROOT(0)
END
//
// 2 bytes in section .near.bss
// 20 bytes in section .near.data
// 84 bytes in section .near_func.text
//
具体含义简单介绍一下:
1. 运行模型结构(Runtime model attributes)
这类东西基本找不到官方的翻译,那就按字面上的意思咯。它主要是对程序整体的一些基础设置,一般要保持代码中所有汇编文件保持一致。在自己写汇编时可加可不加。如果要加的话一定要从同工程下别处原样复制过来,一个符号都不要改
RTMODEL "__SystemLibrary", "DLib" //基础库,包括C和C++所必需的头文件
RTMODEL "__code_model", "small" //代码量,代表寻址空间
//"small" ->最大16KB寻址空间
//"medium" ->最大16MB寻址空间,但函数代码地址不允许超过64KB边界
//"large" ->最大16MB寻址空间,函数代码地址允许超过64KB边界
RTMODEL "__core", "stm8" //芯片型号,只能是"stm8"
RTMODEL "__data_model", "medium" //详见帮助文档
RTMODEL "__rt_version", "4" //同个程序RTMODEL改变时,版本号相应改变
2. 标号声明(Symbol control)
对一些本文件中涉及到的变量名或函数名(地址标号)进行声明,并表示该变量的作用域。
上一篇:STM8S汇编代码分析
下一篇:STM8 symbol _assert_failed not defined (Debugstm8s_adc1.o )
推荐阅读最新更新时间:2024-11-13 12:02
设计资源 培训 开发板 精华推荐
- m.2 模块调试板
- DC2268A-B,用于 LTM4620AEV 双降压模块稳压器的演示板,5.5V = VIN = 16V,Vout1 = 3.3V @ 13A,Vout2 = 1.5V @ 13A
- 使用 Aimtec 的 AM2M-1215D-NZ 的参考设计
- 使用 ON Semiconductor 的 RC4190 的参考设计
- DER-882 - 基于LinkSwitch-HP的小家电隔离式反激式适配器,功率为15W
- LF33CV 3.3V低压灯泡典型应用
- 使用 Analog Devices 的 LT124XCS8 的参考设计
- RGB灯带控制板
- LTC3703 的典型应用 - 100V 同步开关稳压控制器
- LTC2916、1.8V、-5% 电源监视器