查看: 1153|回复: 0
打印 上一主题 下一主题

通过STM8分析c和asm的接口

[复制链接]
跳转到指定楼层
沙发
发表于 2015-5-18 16:58:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
签到 
       
搜索
搜索       
热搜: 净化器雕刻机阿莫邮购
amoBBS 阿莫电子论坛?论坛首页?单片机?STM32/8?通过STM8分析c和asm的接口bottom↓
返回列表发新帖
查看: 3486|回复: 16
打印 上一主题 下一主题 通过STM8分析c和asm的接口 [复制链接]
Flynn1986

电梯直达跳转到指定楼层 1楼
发表于 2012-4-29 23:02:49 | 只看该作者 回帖奖励
本帖最后由 Flynn1986 于 2012-4-29 23:08 编辑


一,首先我在这里不探讨汇编和c的优劣。其实汇编和c没有优劣区分,任何一种高级语言编译生成的目标文件都可以反汇编。
    了解过编译原理的人都清楚,c程序代码经过编译,最终生成二进制机器指令代码,具体的二进制指令数据才是cpu可以译码执行的数据。
    二进制指令和汇编助代码其实是一一对应的,也就是说一条汇编助代码就对应1到多个字节的二进制数据。汇编代码可以让我们从助记符上
    感官地看懂每一条指令干了什么事。在这里发表下我了解汇编一些感受:理解汇编指令代码,你才能更深入的理解cpu是如何执行c程序代码的。
    写一个函数,里面的局部变量时如何在堆栈上生成的;定义一个指针变量是如何间接访问内存的;调用一个函数是如何把不同的参数传递过去的,
    返回的结果存放在哪里等等。只有深入了解编译器和汇编指令,才能写出高效,可靠的程序,因为你编写c代码时,就在预测编译器的意图是否是
    你想要的,同时你的脑袋也在运行你的代码。

二,现在我们就开始以STM8为列,看看c和汇编是如何接口的。学习汇编,只要你花心思了解一个内核的指令系统,学习其他内核的都是举一反三。
    例如我以前非常熟悉51单片机内核的工作过程和指令集。我使用STM8汇编,只要有它内核指令手册,开发编译环境的手册,STM8芯片的手册。
    STM有提供《STM8 CPU programming manual.pdf》,《CXSTM8_UsersGuide.pdf》,《【RM0016】STM8S技术参考手册V4.pdf》。有了以上
    这些数据资料我就可以开始使用STM汇编编程了。最近我在参考AVRUSB的思想在STM8上模拟USB1.0做个usb device。最近碰到一些困难,在指令
    周期上有些不确定,怀疑STM的指令周期不太精确。迟些无论结果怎样,都想在阿莫论坛上跟大家分享下。

    好了,开始啦。。。
    直接看以下汇编代码:
;--------------------------------common inc----------------------------------;
        include "_iostm8a.inc"
;-----------------------------end common inc---------------------------------;

    ; extern func
        xdef   _Sum    ; 声明 _Sum是外部可见的标识符(函数),对应的c调用的函数的原型是 int Sum(int arg1,int arg2,int arg3)

        switch        .text  ; 告诉汇编器以下是代码段
;
; text name: int Sum(int arg1,int arg2,int arg3)
;
_Sum:
;sp[1]~[2]:arg1                 ;调用函数是先把参数3入堆栈
;sp[3]~[4]:arg2                 ;然后把参数2入堆栈
;sp[5]~[6]:return address of pc ;然后把函数返回地址入堆栈
;x        :arg3                 ;参数3保留在x寄存器中
        addw x,(3,sp)                 ; sum  = para1+para2;
        addw x,(5,sp)                 ; sum += para2;
  ret ; return

        end




三,在c文件中调用以上汇编子程序,只要声明下extern int Sum(int arg1,int arg2,int arg3)可以用了。
    大家会发现少了个下划线‘_’,其实这是cxstm8规定的,它与其他编译器不一样,它会自动地把c文件中的外部的标识符(全局变量,外部函数)
    加上下划线'_'。

    例如c代码:
    int i=Sum(11,5,9);
    反汇编:
    ...
    ...
                0xa109 <_main+56>           0xAE0009        LDW   X,#0x0009           LDW   X,#0x0009  
                0xa10c <_main+59>           0x89            PUSHW X                   PUSHW X             ;参数9入堆栈
                0xa10d <_main+60>           0xAE0005        LDW   X,#0x0005           LDW   X,#0x0005
                0xa110 <_main+63>           0x89            PUSHW X                   PUSHW X             ;参数5入堆栈
                0xa111 <_main+64>           0xAE000B        LDW   X,#0x000b           LDW   X,#0x000b     ;参数11保留在x寄存器中
                0xa114 <_main+67>           0xCD9E6F        CALL  0x9e6f              CALL  _Sum
                0xa117 <_main+70>           0x5B04          ADDW  SP,#0x04            ADDW  SP,#0x04
                0xa119 <_main+72>           0x1F09          LDW   (0x09,SP),X         LDW   (0x09,SP),X
    ...
    ...

    以上简单明了地看出c是如何传递参数的值,相信各位都很容易理解的,只要有一定汇编,c语言基础。
    关于更多的c是如何通过汇编实现的,有兴趣的朋友只要多些simulation下,观察反汇编。多些参考《CXSTM8_UsersGuide.pdf》。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表