2004台湾的扬智(ali)科技开始做mp3,最早的产品仅仅断码屏,高速usb 2.0,adpcm录音。当时深圳的盈科一直在做它的产品,对于当时高速usb这一优势,陆陆续续也接到了一些外单。由于其录音的品质很差,返修率高,所以只有几家工厂在做,量一直上不去。2006年我到扬智驻深圳办事处去培训,在他们的公告栏上,写着“月出货量突破3kk”,那个时候,台湾ALI已成为全球最大的MP3芯片供应商之一,其产品音质也相当突出,尤其是ALI的最新解码芯片Ali M5661,还具有USB 2.0接口的MP3+Flash Disk控制芯片,可用于U盘+MP3播放器等解决方案,数据传输速率可以达到目前业界领先的水平,同时它还具有OTG(On-The-Go)、高性能、高度集成化、功能丰富等特点。到后来我接触到了其代码,才发现其合理性,巧妙性。对于ali我所知道的,IC型号有5661p,5661c,m7101,5667;5661p是针对于黑白屏的,5661c彩屏,它们出货的价钱不一样,它们却是同一颗IC,以致于当时深圳的一些方案公司也投入到如何**其原因,极少数的公司找到了答案,修改寄存器obCONTEXTSW----”反汇编”,去看它的汇编语言。充分的证明了一点,知识就是金钱。 2006年无锡华晶推出了3301,其内核的构架与当时的ali,action,segmatel一样,一颗dsp,用于音频,视频的编解码;一颗mcu,用于fat,usb,lcd,key底层的驱动。dsp采用的是飞利浦的内核,品质在行业中是数一数二的;mcu是单指令周期。客观来说,华晶是当时最有优势的,但是这仅仅是从硬件上来说的。读者可以访问他们的网站,intech.ys168.com,你会很清楚他们今天销售的状况;他们已经退出mp3的舞台了,原因就是软件不稳定,很些变量的滥用。我举一个例子,对于一个文件的预先处理,他把一个文件的cluster链表一次性读入buf[];这有一个问题,如果是128M的内存,它无法播放大于90M的文件。 Ali及华晶的IC,有一个非常相似的地方就是其mcu都是51内核,而且都是用keil编译,且都能可以simulate查看其汇编程序。我想如果想让华晶翻身,可能只有充分的理解ali的程序编写,包括变量的定义,主要是绝对地址的定义。但是,ai的核心的mcu程序,包括fat,usb,及逻辑到物理层的程序,最关键的是对flash的处理,都是打包成lib,用户只能调用其接口函数,不能看其源码。我有时闲得无聊,会对看ali的汇编语言,开始比较吃力,后来看多了,也就得心应手,速度也越来越快。我把我的心得写下来,与大家分享,不足之处,请指教.chenshiyangyi@163.com 1.Keil编译环境的设定
进行编译之后会生成038Custm.M51文件,里面有局部变量,全局变量的地址;函数的地址,及函数变量的定义(有的lib会把变量去掉,此时你只能看到其绝对地址,这时你应该区别它是全局的绝对地址,还是局部变量) 下面的编译信息即为封装库里的函数信息. ------- PROC _PHYWRITEPAGEFROMSRAM X:947DH SYMBOL bStorPath ===传递的参数 X:947EH SYMBOL bLen ------- DO D:0055H SYMBOL bb ====局部变量的定义 D:0056H SYMBOL fRet D:0057H SYMBOL bKeepSpeed D:0058H SYMBOL bAdjust ------- ENDDO C:BD3DH LINE# 7843 ……….. C:BE93H LINE# 7995 C:BE94H LINE# 7998 ------- ENDPROC _PHYWRITEPAGEFROMSRAM
可以看出其大体的框架为: PHYWRITEPAGEFROMSRAM(XBYTE bStorPath,XBYTE bLen ) { BYTE bb, fRet, bKeepSpeed, bAdjust
}
2.反汇编代码的获取: 首先编译工程,
点击”start/stop debug session”按钮 点击”disassembly window”
此时你可以将所有的的汇编程序coy到专业的文本编辑框,保存.我所用的是UltraEdit-32,且把文件后缀改为.c;有时进行反汇译时,你可能对一些函数弄不明白,特别是case语句,此时你可以修改右侧的regester及pc ptr.对于case语句的跳转,你可以把switch(cmd),试着把cmd的值输入到r7,把switch的输入地址填入pc $.按F11单步运行就可以了. 您可以点击”Memory window”来查看二进制代码,及xdata,idata变量空间
如果你需要查看xdata 地址为1的变量输入x:0x0001即可
3.汇编语言的模块程序归类
1) DWORD TMP,TMP1 IF(TMP==TMP1) {
} 汇编程序: R4R5R6R7 = TMP1; R0R1R2R3 = TMP; CLR C C?ULCMP JNZ Continue_Proc {
} Continue_Proc: 2) DWORD TMP,TMP1; IF(TMP>TMP1) {
} 汇编程序: R4R5R6R7 = TMP1; R0R1R2R3 = TMP; SETB C C?ULCMP JC Continue_Proc {
} Continue_Proc: 3) DWORD TMP,TMP1; IF(TMP>=TMP1) {
} 汇编程序: R4R5R6R7 = TMP1; R0R1R2R3 = TMP; CLR C C:ULCMP JC Continue_Proc {
} Continue_Proc:
4) DWORD TMP,TMP1; IF(TMP<TMP1) {
} 汇编: R4R5R6R7 = TMP1; R0R1R2R3 = TMP; CLR C C:ULCMP JNC Continue_Proc {
}
Continue_Proc: 5) DWORD TMP,TMP1; IF(TMP<=TMP1) {
} 汇编语言: R4R5R6R7 = TMP1; R0R1R2R3 = TMP; SETB C C:ULCMP JNC Continue_Proc {
} Continue_Proc: 6) DWORD TMP,TMP1; TMP/TMP1; 汇编: R4R5R6R7 = TMP1; R0R1R2R3 = TMP; C?ULDIV 其中,商放到:R4R5R6R7;余数放在:R0R1R2R3
WORD TMP,TMP1; TMP/TMP1 汇编: R6R7 = TMP; R4R5 = TMP1; 运算的结果商:R6R7,余数:R4R5 7) DWORD TMP,TMP1; TMP*TMP1; 调用C?LMULP 积放到:R4R5R6R7
8) DWORD(XDWORD) TMP1; BYTE(XBYTE) BI;
TMP1>>BI
汇编语言: R4R5R6R7 = TMP; R0 = BI; C?ULSHR , 结果放在:R4R5R6R7 由于此文档有一些图片,无法链接,我把此份文档上传至 “http://www.sokutek.com/document.asp“,“sokutek.com/document.asp“,
|