打印
[Cortex-M0技术交流]

无耻炫耀一把,ZENYIN同学终于用汇编搞定了CM4

[复制链接]
楼主: zenyin
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zenyin|  楼主 | 2016-10-22 14:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
月球上一小步,地球上一大步,完全靠个人摸索出来,虽然时间用得很长,但理解更深刻,个中的充斥了苦与乐
在网络上能找到一些例程,即使拷贝下来,很难直接拿来用,原因是太多莫名其妙的伪指令和太多语法错误,还有开发平台一般有两种,KEIL和ADS,在不同平台上写的程序,也不能直接移植。
本文为大家提供一个几乎是赤裸裸的汇编例程,完成这样的操作:PA7和PA6两只发光二极管0.5秒左右交替闪烁
程序非常短小,如果不考虑是学习CM4的话,可以说只有寥寥几十条程序,足见汇编语言的极高效率,如果用高级语言编程,即使不上操作系统采用裸奔,那怕编一条程序,程序规模都是20K以上,用汇编只需要几百个字节就搞定了。

芯片用的是STM32407VET6 开发环境为KEIL_V5

相关帖子

沙发
zenyin|  楼主 | 2016-10-22 15:53 | 只看该作者
                  
                             AREA     |RESET|, CODE, READONLY          ;程序开篇伪指令就这么一条,告诉编译程序,这是只读的程序代码
                             ;指令和伪指令不能定格 定格则表示标号 ,标号后面不能加冒号 空格就行了,不要受51单片机影响       
  
                                    DCD     0x20000400        ;堆栈顶
                                DCD     START                     
                                DCD     NMI_Handler                ; NMI Handler
                                DCD     HardFault_Handler          ; Hard Fault Handler
                                DCD     MemManage_Handler          ; MPU Fault Handler
                                DCD     BusFault_Handler           ; Bus Fault Handler
                                DCD     UsageFault_Handler         ; Usage Fault Handler
                                DCD     0                          ; Reserved
                                DCD     0                          ; Reserved
                                DCD     0                          ; Reserved
                                DCD     0                          ; Reserved
                                DCD     SVC_Handler                ; SVCall Handler
                                DCD     DebugMon_Handler           ; Debug Monitor Handler
                                DCD     0                          ; Reserved
                                DCD     PendSV_Handler             ; PendSV Handler
                                DCD     SysTick_Handler            ; SysTick Handler                       
                                       
                                 ENTRY    ;这个伪指令告诉是程序入口         
;****************************程序入口*************************************           
START                NOP      
                         NOP       
;*******************************************外设复位和初始化时钟**************************************                               
                               
                                MOV R3,#0X3800  
                                MOVT R3,#0X4002   ;RCC首地址                                        
                                LDR R4,[R3,#0X24]                   
                                ORR R4,#0X01       ;将PA的时钟打开
                                STR R4,[R3,#0X30]  ;写回去就打开了PA的时钟               
                               
;***************************************GPIO操作********************************************
                                MOV R3,#0X0000   
                                MOVT R3,#0X4002   ;GPIOA首地址                                       
                                MOV R4,#0XFFFF      ;(R4)=0XFFFF ,GPIO输出最好为高和51单片机一样
                                STR R4,[R3,#0X14]                                        
                                LDR R4,[R3]               ;把PA口的输出模式寄存器的值读回来,其中PA15PA14PA13是专用链接JTAG,不能修改
                                ORR R4,#0X00005000    ;将PA7和PA6修改成输出模式,默认为输入模式                       
                                STR R4,[R3]                  ;回写回去
                                LDR R4,[R3,#0X04]      
                                ORR R4,#0X000000C0     ;把PA7PA6写成开漏模式
                                STR R4,[R3,#0X04]       ;写回去                               
                                MOV R4,#0X0040                         
                                MOVT R4,#0X0080     ;采用位操作方式控制PA7和PA6 其中一个复位一个置位
                                STR R4,[R3,#0X18]   ;至此两只发光二极管开始一只亮一只灭
                                MOV R5,#0X00C000C0    ;R5对这两位进行异或运算,这里相当于取反
                               
YS                        MOV R2,#0X00200000   ;软件延时0X00200000个脉冲  软件延时
LJ                         SUBS R2,#0X01             ;减1不为零继续减---连续减     
                            BNE LJ                           ;此三条指令相当于51单片机 DJNZ
                            EOR R4,R5        ;将输出每次定时到取反               
                           STR R4,[R3,#0X18] ;将取反后的输出状态以位操作方式输出去
                           B YS                 ;重新赋值再次定时循环

;************************************以下是Cortex-M4F的内部中断服务程序**********************
NMI_Handler     NOP
                      NOP
                      NOP
                      NOP
                       BX LR       
                               
                               
HardFault_Handler         NOP
                                  NOP
                                   NOP
                                   LDR R3,[SP,#28]  
                                   ADD R3,#0X01000000
                                   STR R3,[SP,#28]
                                    NOP
                                    NOP
                                    NOP
                                   BX LR      
                                  
                                  
            
MemManage_Handler       NOP
                                   NOP
                                   NOP
                                   NOP
                                   BX LR

BusFault_Handler           NOP
                                   NOP
                                   NOP
                                   NOP
                                   BX LR
                                  
                                  
UsageFault_Handler        NOP
                                   NOP
                                   NOP
                                   NOP
                                   BX LR

SVC_Handler        NOP      ;软中断读取参数,主要是由用户特权模式改变为线程访问
                         NOP                
                        PUSH {R0-R12,LR}    ;浏览一下堆栈是怎么压栈
                        NOP
                        MOV R14,#0XFE00FE00       
                        POP {R0-R12,LR}                     
                        NOP                          
                        NOP       
                        LDRB R3,[SP,#24]
                      TST LR,#0X00000004                   
                      BEQ DSVCS
                      MRS R3,PSP  
                      LDRB R3,[R3,#24]               
DSVCS                  NOP
                     NOP
                     LDRB R3,[R3,#-2]          
                    NOP
                   NOP     
                   BX LR  
DebugMon_Handler   NOP
                             NOP
                             NOP
                             NOP
                            BX LR
PendSV_Handler     NOP
                           NOP
                           NOP
                           NOP
                           BX LR
SysTick_Handler    NOP       ;滴答时钟中断
                          NOP  
                          NOP
                          NOP
                         MOV R3,#0XE000E000
                         LDR R3,[R3,#0X10]  
                         BX LR  
;***********************************************下面是程序结尾***************************         
                         NOP   ;这个NOP非常重要,当指令不能四字节对齐,而是半字对齐时就加一个NOP 否则就删除NOP,汇编将无告警
                         END    ;END伪指令告诉编译器程序结束

使用特权

评论回复
板凳
zenyin|  楼主 | 2016-10-22 16:08 | 只看该作者
                                AREA     |RESET|, CODE, READONLY
   
                                DCD     0x20000400        ;堆栈顶
                                DCD     START                     
                                DCD     NMI_Handler                ; NMI Handler
                                DCD     HardFault_Handler          ; Hard Fault Handler
                                DCD     MemManage_Handler          ; MPU Fault Handler
                                DCD     BusFault_Handler           ; Bus Fault Handler
                                DCD     UsageFault_Handler         ; Usage Fault Handler
                                DCD     0                          ; Reserved
                                DCD     0                          ; Reserved
                                DCD     0                          ; Reserved
                                DCD     0                          ; Reserved
                                DCD     SVC_Handler                ; SVCall Handler
                                DCD     DebugMon_Handler           ; Debug Monitor Handler
                                DCD     0                          ; Reserved
                                DCD     PendSV_Handler             ; PendSV Handler
                                DCD     SysTick_Handler            ; SysTick Handler                 
                                       
                                ENTRY    ;这个伪指令告诉是程序入口   
      
;****************************程序入口*************************************           
START                           NOP      
                                    
                        

;*******************************就在NOP编我们的程序,下面就是中断服务程序********

NMI_Handler     
                        NOP
                        
                       ;在此填写中断服务程序
                 
                        BX LR        
                                
                                
HardFault_Handler         NOP
                          
                                 
                                 
                          BX LR      
                                   
                                   
            
MemManage_Handler          NOP
                           

                           BX LR

BusFault_Handler           NOP
                           

                           BX LR
                                   
                                   
UsageFault_Handler         NOP
                                   
                                   
                           BX LR

SVC_Handler        NOP  
                  
                   BX LR   
DSVCS              NOP

                   BX LR

DebugMon_Handler   NOP
                     
                   BX LR

PendSV_Handler     NOP
                        
                   BX LR

SysTick_Handler    NOP      
                        
                   BX LR  
;***********************************************下面是程序结尾***************************  
        
                   NOP   ;NOP 可加也可屏蔽

;这个NOP非常重要,当指令不能四字节对齐,而是半字对齐时就加一个NOP 否则就删除NOP,汇编将无告警

                   END    ;END伪指令告诉编译器程序结束


;这个就是汇编语言的架子,只用到三个伪指令,干净利索,完全没有看不懂的错误,也几乎没有搞不懂的告警。
                           

使用特权

评论回复
地板
zenyin|  楼主 | 2016-10-22 16:10 | 只看该作者
如果在网上或者教材上拷贝一个历程下来,准保我们搞不顶,原因一平台不一样 二。总有语法错误  三。一大堆定义和伪指令让人莫名其妙

使用特权

评论回复
5
zenyin|  楼主 | 2016-10-22 16:10 | 只看该作者
如果在网上或者教材上拷贝一个例程下来,准保我们搞不定,原因一:平台不一样 二。总有语法错误  三。一大堆定义和伪指令让人莫名其妙

使用特权

评论回复
6
zenyin|  楼主 | 2016-10-22 16:21 | 只看该作者
上面全部程序,对于高级语言而言例如C,这样的规模连初始化一个GPIO口都不够,更何况高级语言一大堆启动程序,汇编语言大约只需要1/20程序就够了足见汇编语言效率有多高,既然成功走出第一步,ZENYIN同学下一步将把所有驱动程序用汇编语言写出来,以后直接裁减就是,ZINYIN相信,鉴于ARM是32位和丰富的硬件远比51单片机更强大,未来除非涉及复杂的数**算,搞任何一个项目,全部程序都不会超过2K,因为ARM指令的解析度更高,2K是什么感念呢,CM4指令有四字节和2字节,平均3字节 2K程序,对应大约600条指令

使用特权

评论回复
7
Simon21ic| | 2016-10-22 20:17 | 只看该作者
基本只有逆向或者**打patch的时候才用到汇编

使用特权

评论回复
8
xinxi| | 2016-10-23 08:38 | 只看该作者
没有字对齐的伪指令?

使用特权

评论回复
9
sherwin| | 2016-10-23 09:47 | 只看该作者
点赞!顶一把。

使用特权

评论回复
10
通宵敲代码| | 2016-10-23 12:07 | 只看该作者
好久不研究汇编了,
太累人了!

使用特权

评论回复
11
kingTek| | 2016-10-23 13:35 | 只看该作者
为学汇编的人点赞!

使用特权

评论回复
12
王奉瑾| | 2016-10-23 13:50 | 只看该作者
很多年不见了
哈哈

使用特权

评论回复
13
zenyin|  楼主 | 2016-10-24 11:45 | 只看该作者
王奉瑾 发表于 2016-10-23 13:50
很多年不见了
哈哈

朝奉先生现在招商银行行长哈,现在是活身体哦,人在阵地在,现在朝奉先生不是继续追求,品德高业务理论水平业务水平高的时分了,现在是新三高,老哥怎么样?悠着点人在阵地在哦:)

使用特权

评论回复
14
zenyin|  楼主 | 2016-10-24 11:48 | 只看该作者
通宵敲代码 发表于 2016-10-23 12:07
好久不研究汇编了,
太累人了!

山东好汉,张庄的?太累的太,是一人下面多一点---男人嘛----田里的劳动力----田力为男!!
为什么累呢------男人心系自己天肯定累---累=系田!

使用特权

评论回复
15
zenyin|  楼主 | 2016-10-24 11:50 | 只看该作者
通宵敲代码 发表于 2016-10-23 12:07
好久不研究汇编了,
太累人了!

潍坊兄弟,埋头写代码,颈椎会扯拐,在潍坊放放风筝吧,对颈椎非常好,抬头望天,低头看路,上下间骨头就润滑了!

使用特权

评论回复
16
zenyin|  楼主 | 2016-10-24 11:52 | 只看该作者
xinxi 发表于 2016-10-23 08:38
没有字对齐的伪指令?

有强制位对齐伪指令  ,我讨厌一切繁文缛节!因为我下一步要手工汇编机器码,变态不!

使用特权

评论回复
17
zenyin|  楼主 | 2016-10-24 12:03 | 只看该作者
本帖最后由 zenyin 于 2016-10-24 12:16 编辑

下一步,有个打算,反汇编,人工就太低效了,用单片机-机器来反汇编机器码,这方面书不多完全是一种自虐!!但一定跑不出,”指令编码 条件码  目的寄存器, 符号写与不写 第二寄存器,第二操作数  “这种套路  例如ADD R3,R4,#0X3E7,从这条指令估计:指令表达式不会超过六位,则64种字母组合。两个寄存器需要8比特来表达,条件需要4比特表达,还有有一位用于区分是ARM模式和THUMB    算算6+4+4+1+4+12+1=32,竟然刚好:)把64种情况散转出来,最后用ASC码输出方式串口直接输出到计算机上,出来就是不带符号地址的“落体”汇编程序 。**光身子竟然是非法词汇。

使用特权

评论回复
18
xydzx| | 2016-10-29 10:39 | 只看该作者
大家好,打扰一下,信盈达开设有:嵌入式、安卓、Java、单片机、PCB、FPGA、ARM、C语言、电子等课程,全部免费试听。北京,郑州,深圳南山、民治、西乡、广州、南宁七大中心同时开课
有需要的请回复联系方式+试听课程QQ:3026827905  
微信:17778038831

使用特权

评论回复
19
通宵敲代码| | 2016-10-31 14:06 | 只看该作者
zenyin 发表于 2016-10-24 11:50
潍坊兄弟,埋头写代码,颈椎会扯拐,在潍坊放放风筝吧,对颈椎非常好,抬头望天,低头看路,上下间骨头就 ...


脖子扭扭、屁股扭扭···

使用特权

评论回复
20
yjmwxwx| | 2016-11-25 19:37 | 只看该作者
我以前也写STM32的汇编,但是家里没机会实践条件有限,各种器件的控制方法不懂不实践根本学不会。 什么PID算法、视频音频解码都不懂,写程序不是问题关键是太多东西不懂,基础差搞不下去了。 去公司应聘人家都不搭理我,于是干脆放弃老老实实种地了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

90

主题

393

帖子

5

粉丝