历史上的今天
返回首页

历史上的今天

今天是:2025年02月01日(星期六)

2020年02月01日 | STM8 汇编学习笔记2: 开发环境

2020-02-01 来源:eefocus

写在前面

就我所知,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)

对一些本文件中涉及到的变量名或函数名(地址标号)进行声明,并表示该变量的作用域。

推荐阅读

史海拾趣

Diode Laser Concepts公司的发展小趣事

Diode Laser Concepts公司始终关注社会责任,积极参与各类公益活动。公司定期向贫困地区捐赠教育设备和资金,支持当地的教育事业发展;同时,公司还组织员工参与环保志愿活动,宣传环保理念,为保护地球环境贡献一份力量。这些公益活动不仅体现了公司的社会责任感,也增强了员工之间的凝聚力和向心力。

Dynawave Incorporated公司的发展小趣事

Dynawave Incorporated的创始人李明,是一位在电子行业有着丰富经验的工程师。他深知随着科技的发展,无线通信技术将成为未来发展的重要方向。因此,李明带领一支技术团队,夜以继日地研发新型无线通信技术。经过数月的努力,他们成功开发出了一种具有高效能、低能耗特点的无线传输技术,这一技术为Dynawave在行业中赢得了初步声誉。

Good Sky Electric Co Ltd公司的发展小趣事
正确操作摇臂钻床的关键在于遵循操作规程和安全规范。在操作过程中,应注意避免超负荷运行、频繁启动和停止以及长时间连续工作等不当操作。同时,还应定期对设备进行维护保养,如清洁电气元件、检查接线是否松动、更换老化的元件等。
天钰(FITIPOWER)公司的发展小趣事
电机过热可能是由于负载过大、电机散热不良、电源电压不稳定或电机内部故障等原因造成的。在排查时,可以首先检查电机负载是否超出额定范围,然后检查散热系统是否正常运行,如风扇是否转动、散热片是否清洁等。同时,还应检查电源电压是否稳定,以及电机内部是否有短路或断路现象。
Eastman Kodak Company公司的发展小趣事

随着技术的不断进步,伊士曼柯达公司不断推出新的产品和服务,以满足市场的多样化需求。在20世纪初,柯达已成为全球最大的胶卷供应商,并占据了美国摄影市场的绝大部分份额。此外,公司还积极向国际市场扩张,通过设立分支机构和办事处,将产品销往全球各地。这一时期,柯达不仅凭借其优质的产品赢得了广泛的客户基础,还树立了良好的品牌形象。

上海晶丰明源(BPS)公司的发展小趣事

近年来,晶丰明源在电源管理芯片领域取得了多项技术突破。公司成功研发出多款高性能、低功耗的芯片产品,广泛应用于智能手机、平板电脑、智能家居等领域。同时,公司还积极拓展海外市场,与多家国际知名厂商建立了合作关系,产品出口至全球多个国家和地区。这些技术突破和市场拓展的成果,进一步巩固了晶丰明源在行业内的领先地位。

问答坊 | AI 解惑

上市不重要;商业模式重要

上市不重要;商业模式重要      商业模式是影响一个企业发展、融资、上市非常重要的因素。不同商业模式的企业应选择不同的上市地。反之,欲在不同地方或者同一地方不同市场上市的企业应根据自己的融资需求预先设计自己独特的 ...…

查看全部问答>

发个nrf24l01的资料加使用电路图 PCB图

买的的nrf24l01 做了个板子 调试了一下,是成功了的!!程序没传上来,有兴趣根据资料修改修改就可以啦!! 大家多多交流!!…

查看全部问答>

做Zigbee通信实验

公司里有用Cortex-M3做的,我想换一款芯片试试,具体想做什么暂时还没想好,等想好了再补上吧,暂时先占个坑,呵呵!!…

查看全部问答>

请问一个模拟电路问题

请问在基本共射放大电路里面U0=-Ic(Rc//Rl)这个式子如何来的?Rc,Rl中应该没有电流通过啊?谢谢…

查看全部问答>

要做云台解码器程序该怎么入手?

小弟最近想学习写一个监控摄像头云台解码器的程序。但不不知道如何才能入手。 不知道高手有何建议?或者有程序给小弟参考一下也可以。不胜感激。…

查看全部问答>

版主指教,二次技改,替换TMS320F2812,2407

                                 版主指教,二次技改,用STM32替换TMS320F2812,2407,用STM32哪个型号比较好?…

查看全部问答>

纳米测量电流误差解决方案

其他应对移动和振动[1]问题的解决方案包括: •除去振动源或者与振动源间在机械上解耦。电机、水泵和其他机电装置都是常见的振动源[2]。 •稳定整个测试环境。保证电子元器件、导线和电缆的稳固安装或者捆绑固定。屏蔽[3]应该保证稳 ...…

查看全部问答>

给本次ADI实验室电路DIY大赛参赛者的一点后续建议

建议获奖者包括其它未获奖者和未如期完成作品的参赛者继续改进自己的作品,这不仅仅是动手实践提高自己技术能力的一次机会,好的DIY作品本身也是一件实用的装置,善于利用的话,也许还能成为一块不错的“敲门砖”,特别是对于还是学生的参赛者,同 ...…

查看全部问答>

LPC2103外部中断0

我仿真的时候没有问题可以,把程序下到板子里问题就出来了,为什么我把触发方式设置成边沿触发,把程序下到板子里就先执行了一次中断服务程序,而我在Protues仿真的时候就是好的,我有点郁闷了。怀疑是不是硬件的原因。板子放了很久,复位按钮更奇 ...…

查看全部问答>

QT编程怎样操作ARM寄存器

请问用QT编程能直接在嵌入式linux中直接操作ARM寄存器吗?如果能,是直接在代码中操作还是要什么特殊处理?…

查看全部问答>