最近打算玩一下STM8, 只为了消化一下我的库存,因为我曾经买过几个型号的STM8单片机,但是一直没用来DIY啥。我对STM8熟悉程度远不如STM32, 后者是流行广泛的ARM核,STM8却是ST独家的架构。
STM8 CPU是在ST7基础上增强,有人说是从6502演变来的,我看倒也不像。学习了一下历史,Motorola的6800演变出来的6805/6811/6809三个分支,以及6502这个与6800有渊源的CPU,从寄存器和指令集上看STM8是和它们有相似之处的,不过差异的地方也很大。作为一个8位MCU,STM8的寻址范围居然达到16M byte(我不信ST会给8位机配上1M以上的ROM或RAM),寻址模式就很多了,间接内存访问比x86都复杂,看惯了RISC的CPU更不能忍。好吧,虽然指令集复杂,STM8的执行速度还快,反正不会纯用汇编来开发。
ST并没有提供STM8的C编译器(汇编器是有的),需要用第三方的。Cosmic C编译器有免费License的版本可以用,这也是ST推荐的,我就装了一个来试。ST官方支持的还有Raisonance的编译器,此外IAR也有STM8的开发环境。
试写了个C程序测试,可以用STVP连接ST-Link下载程序,但我觉得还需要个能反汇编看编译结果的东西。Cosmic工具链里面没有反汇编程序,ST的汇编工具里也没有,STVD既然能跟踪调试应该有,但我没能把它用起来。
干脆自己写一个STM8反汇编工具吧,也练下手怎么写。
先研究下STM8的指令集,这是一种典型变长指令集,除了前缀字节,操作码就在一个字节里面。于是我照着手册统计了一张表出来:
一个字节能表示的范围除了 0x90, 0x91, 0x92, 0x72 用来做指令前缀,其它几乎都用来作操作码了。当然许多指令都有多种寻址模式的(比如加法是谁和谁相加,需要指定),因此用了不止一个操作码。算上寻址模式,256种指令都不够用的,所以STM8靠前面增加前缀字节来扩展。从手册里面截一个例子如下(这是XOR指令的多种编码):
在指令的操作码后面就是提供数据或地址的字节了,长度由操作码加上前缀来决定。
编写反汇编程序就是写一个根据字节数据流的查表过程。上面我做的那个表只是划分了指令的分布,涉及到寻址模式的细节还是得一边写一边查手册。从表上看,操作码的高半字节大概可以把指令划分为几类,再用低半字节去细分指令,于是我的程序解码第一步就是一个 switch-case 结构来划分任务:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | int decode_instr(unsigned char opcode) { switch(opcode>>4) { case 1: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0E: case 0x0F: return decode_group1(opcode); case 0: case 3: case 4: case 6: case 7: return decode_group2(opcode); case 5: if(Prefix==0x72) return decode_group2(opcode); else return decode_5x(opcode); case 8: return decode_8x(opcode); case 2: return decode_2x(opcode); case 9: return decode_9x(opcode); default: return -1; } } |
解码的结果是放到全局变量里面的,返回值只代表了指令是否有效。例如,表格最右边一列的指令我是这样解析的:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | int decode_9x(unsigned char opcode) { AutoXY=1; switch(opcode&0x0f) { case 0: return set_prefix(0x90); case 1: return set_prefix(0x91); case 2: return set_prefix(0x92); case 3: format(0, LDW, regX, regY); format(0x90, LDW, regY, regX); return 1; case 4: format(0, LDW, regSP, regX); return 1; case 5: format(0, LD, regXH, regA); return 1; case 6: format(0, LDW, regX, regSP); return 1; case 7: format(0, LD, regXL, regA); return 1; case 8: format(0, RCF, 0, 0); return 1; case 9: format(0, SCF, 0, 0); return 1; case 0xA: format(0, RIM, 0, 0); return 1; case 0xB: format(0, SIM, 0, 0); return 1; case 0xC: format(0, RVF, 0, 0); return 1; case 0xD: format(0, NOP, 0, 0); return 1; case 0xE: format(0, LD, regA, regXH); return 1; case 0xF: format(0, LD, regA, regXL); return 1; default: return -1; } } |
主要是靠 format() 函数根据当前的指令前缀来翻译操作码:指令名称,寻址的第一操作数、第二操作数。若一共写 256 个 case 分支就太繁琐了,需要抓住共性,像表格中绿色背景的这一组指令我是这么处理的:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | int decode_group2(unsigned char opcode) { int instr; AutoXY=1; switch(opcode&0x0f) { case 1: switch(opcode>>4) { case 0: format(0, RRWA, regX, 0); return 1; case 3: format(0, EXG, regA, longmem); return 1; case 4: format(0, EXG, regA, regXL); return 1; case 6: format(0, EXG, regA, regYL); return 1; default: return -1; } break; case 2: switch(opcode>>4) { case 0: format(0, RLWA, regX, 0); return 1; case 3: format(0, POP, longmem, 0); return 1; case 4: format(0, MUL, regX, regA); return 1; case 6: format(0, DIV, regX, regA); return 1; case 7: return set_prefix(0x72); } break; case 5: switch(opcode>>4) { case 3: format(0, MOV, longmem, imm8); return 1; case 4: format(0, MOV, mem, mem); return 1; case 6: format(0, DIVW, regX, regY); return 1; default: return -1; } break; case 0xB: switch(opcode>>4) { case 3: format(0, PUSH, longmem, 0); return 1; case 4: format(0, PUSH, imm8, 0); return 1; case 6: format(0, LD, offSP, regA); return 1; 关键字:STM8 反汇编工具 引用地址:徒手编写了一个STM8的反汇编工具
上一篇:STM8单片机CAN滤波器的设置 推荐阅读 8月30-31日,由中国高科技行业门户OFweek维科网、高科会主办,OFweek人工智能网、OFweek医疗科技网承办的2018中国(上海)国际人工智能展览会暨OFweek(第二届)人工智能产业大会在上海跨国采购会展中心成功举办。本次大会共汇集了人工智能领域的国际知名企业高层、行业资深专家、专家分析机构等数千位精英,用全新视角透析行业动态,解读人工智能领域本...
一、定时器STM32F1系列的产品,除了互联型产品外,工位8个定时器 TIM6、TIM7是基本定时器,TIM2、3、4、5是通用定时器,TIM1、TIM8是高级定时器基本定时器1.时钟源定时器时钟TIMxCLK,即内部时钟CK_INT,经APB1预分频提供。在STM32L4:Tim1是高级时钟可做PWM输出Tim15、Tim16是通用时钟,他们的时钟来源是APB2总线Tim2、Tim3通用时钟,Tim6,Tim7基本时钟的时...
据 Windowslatest 报道,尽管 Surface Duo 目前仍无法直接购买,但这款手机的续作已在研发之中了。 根据多个微软 Android 操作系统工作清单显示,微软备受期待的 Surface Duo 现在可以预订,同时 Surface Duo 2 的研发工作已经开始。 IT之家了解到,下一代 Surface Duo 内部代号为 Zeta,除此以外目前尚无更多有关 ...
近日,晶盛机电在接受机构调研时表示,截至2021年6月30日,公司未完成晶体生长设备及智能化加工设备合同总计114.5亿元,其中未完成半导体设备合同6.44亿元。(以上合同金额均含增值税)。公司产品种类较多,不同产品交货周期不同,主要在3-6个月左右。在设备验收时确认收入。其称,上半年,受下游需求拉动及贸易政策影响,国内半导体产业呈现快速发展势头...
史海拾趣 DLP Design公司的发展小趣事
DLP联合科技公司,通过与国内外知名企业的技术合作,实现了技术的快速迭代和产品的升级换代。公司积极寻求与产业链上下游企业的合作机会,共同研发新技术、新产品。通过与合作伙伴的紧密合作,DLP联合科技在DLP技术领域取得了显著成果,为电子行业的发展做出了积极贡献。 AVX公司的发展小趣事
AVX公司的历史可以追溯到XXXX年,当时它由一群热衷于电子技术的工程师创立。在创立初期,AVX主要专注于电容器的研发与生产,凭借其独特的技术和卓越的品质,很快在市场中脱颖而出。随着业务的扩展,AVX逐渐在电感器、电阻器等领域也取得了显著进展,为公司的后续发展奠定了坚实的基础。 芯佰微(Corebai)公司的发展小趣事
芯佰微非常重视技术研发和专利积累。公司拥有一支高素质的研发团队,不断投入资源进行新技术和新产品的研发。同时,芯佰微也积极申请各类专利,保护自己的技术成果。经过多年的积累,芯佰微已经成功申请并获得了数十项专利,这些专利不仅提升了公司的技术实力,也为公司的未来发展提供了有力保障。 American Custom Components公司的发展小趣事
American Custom Components公司始终将产品质量放在首位。为了提升产品质量和客户满意度,公司引进了一套先进的质量管理体系,并定期对员工进行质量意识和技能培训。此外,公司还建立了完善的客户服务体系,及时收集和处理客户的反馈意见,不断优化产品和服务。这些举措使得公司的产品在市场上保持了良好的口碑和竞争力。 Crystek公司的发展小趣事
为了进一步扩大市场份额和提升品牌影响力,Crystek公司积极拓展国际市场,与全球多家知名企业建立了合作关系。通过与这些企业的深入合作,Crystek公司的产品得以广泛应用于无线、微波无线电、电信、工业、企业、航空航天和政府部门等各个领域。同时,公司还积极参加国际电子展览和技术交流会议,与全球同行交流学习,不断提升自身的技术水平和市场竞争力。 Custom Connector Corporation公司的发展小趣事
在追求经济效益的同时,CCC也注重环境保护和可持续发展。公司积极采用环保材料和生产工艺,减少对环境的影响。同时,CCC还积极参与环保公益活动,推动环保理念在员工和社会中的普及。这种环保理念不仅提升了CCC的企业形象也为其在竞争激烈的市场中赢得了更多优势。 请注意,以上故事仅为概述,具体内容和细节可能需要根据实际情况进行补充和完善。同时,由于篇幅限制,每个故事的字数可能无法完全达到500字的要求。
小广播
推荐内容
热门活动
换一批 更多
设计资源 培训 开发板 精华推荐
最新单片机文章
更多精选电路图
更多每日新闻
更多往期活动
11月13日历史上的今天
厂商技术中心
随便看看
|