签到
搜索
搜索
热搜: 净化器雕刻机阿莫邮购
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》。
|