戚心空间 https://passport2.21ic.com/?14797 [收藏] [复制] [RSS]

日志

也谈谈混合编程

已有 806 次阅读2006-10-22 18:39 |个人分类:技术手记|系统分类:单片机


好久没来21IC了,突然发现这里还有自己的一亩三分地,呵呵,可惜已经荒芜的太久了。


   前阵在中国电子论坛上应朋友之邀讨论了下混合编程的问题,今天挪到这里引引砖头吧。


 


环境:keil, C8051


 


1、直接嵌套



在C程序中嵌套ASM语句.一般来说我很少这样用,但有时考虑到执行速率及执行频率较高,直接对ACC,DPTR之类操作的时候,感觉还是


有一定的优势.但该类操作情况下风险系数较高,要充分考虑编译器对相应资源的占用情况.其常用格式如下:


*---------------------------------------------------------
*1、#pragma asm/endasm:
*---------------------------------------------------------
*  可以用#pragma asm 和 #pragma endasm 预处理指示器来在你的C语言程序中插入汇编指令。
*  将此源文件加入要编译的工程文件,
*  将光标指向此文件,选择右键菜单“option for file 'asm.c'”,
*  将属性单“properties”中的“Generate Assembler SRC File”“Assemble SRC File”
*  两项设置成黑体的“√”将“Link Public Only”的“√”去掉,再编译即可。
*  用此方法可以在c源代码的任意位置用#pragma asm和#pragma endasm嵌入汇编语句。
*  但要注意的是在直接使用形参时要小心,在不同的优化级别下产生的汇编代码有所不同,
*  可以察看对应的.lst文件看一看,得到正确的优化级别后,#pragma OT(x,speed)锁定
*  优化级别(这里的值是0-9)。  


2、C中调用汇编函数


其次是我们常说的模块调用的问题了,其实跟C中函数调用无太大区别,不要被编译器自己编译的一大堆???PR,CO??之类的迷惑,关于这类问题可以先放一边.


注意:



*  1、指定代码及数据段(segment)
*  2、声明外部变量及相关定义(extrn)
*  3、带参数函数调用先对参数进行声明(?fun_name?parameter_byte)


*  汇编与C中实现数据传输可通过两种方式:
*  1、利用工作寄存器进行数据传送,这种方式安全,但根据传送数据的类型不同,只能传送1--3个参数。
*
*                              利用寄存器传递参数的规则
*  参数数量     char        int        long,float          一般指针
*  1个参数      R7          R6,R7      R4--R7              R1,R2,R3   ;R6--high
*  2个参数      R5          R4,R5      R4--R7              R1,R2,R3   ;R4--high
*  3个参数      R3          R2,R3      ------              R1,R2,R3

*  func1(int a):"a"在R6/R7中传递
*  func2(int b, int c, int *d):"b"和"c"分别在R6/R7,R4/R5中传递,"d"在R1/R2/R3中传递
*  func3(long e,long f):"e"在R4/R5/R6/R7中传递,"f"在参数段中传递
*
*  2、指定特定的数据区(存在危险性)



CASE:



asm模块定义:


;=========================================================
; 文件名:  asm_MATH_module.asm
;=========================================================
#include "c8051F120.inc"


      NAME asm_MATH_module                  ;函数名声明
     
      ;---------------------------------------------------------
      extrn     data     (now_addr )          ;外部变量声明   
      extrn     data     (Col_Point)
      extrn     data     (Rel_Point)      
      
    extrn     bit     (b_row     )
      extrn     bit     (b_idel    )   


      
  public   asm_Character_Find    ;函数声明

      
      ;--------------------------------------------------  
      ;代码及内存分配段声明
      asm_MATH_rountines segment code              ;函数代码段声名


;;========================================================
;代码段定义:占用CODE断        
       rseg asm_MATH_rountines                     ;函数代码段声名      
;========================================================
asm_Character_Find:


        nop


        ret


        end



2\函数调用


alien void asm_Character_Find(void);              //外部声明



main()


{


             asm_Character_Find();             


}


 


3、关于带参数的场合




      NAME ASM_SUB_PRO                      ;函数名声明
     
      extrn    data    (xcont)              ;外部变量声明      
      ;extrn   code    (fun_name)           ;外部汇编函数声明
     
      public   asm_sub
      public   asm_nop     
     
      ;--------------------------------------------------  
      ;代码及内存分配段声明
      asm_sub_rountines segment code        ;函数代码段声名


      constvar  segment code             ;常量代码段声名  
      datavar   segment data                ;函数代码段声名
      bitvar    segment bit                 ;函数代码段声名


;========================================================
;C中带参数函数调用时:参数声明  
      fun_parameters segment data
                 
      public  ?asm_sub?byte                 ;函数局部变量传送段声明
   public  ?asm_nop?byte


      rseg    fun_parameters
?asm_sub?byte:
?asm_nop?byte:
      ds      2                             ;单字节定义 DS
     
;========================================================
;代码段定义:占用CODE断        
       rseg asm_sub_rountines               ;函数代码段声名


asm_sub:
       mov    a,xcont                       ;外部变量调用    
       mov    a,?asm_sub?byte               ;参数处理
       mov    dptr, #val_array
       movc   a,@a+dptr          ;get a value from array
       ;mov    r6, #0            ;return value hi byte
       ;mov    r7, a             ;return value lo byte
       ;if you return a uchar type value,
       ;the retruned value in ACC
       ;if you return a int type value,
       ;the returned value in R6,R7 reg pair
      
       lcall  asm_nop                    ;汇编内部函数调用
      
       ret
      
val_array:
       db 1,2,3,4,5,6,7,8,9,10
      
asm_nop:
       nop
       djnz ?asm_nop?byte,asm_nop       
       ret
      
;========================================================
;常量段定义:占用CODE断     
 rseg  constvar
context:db    'test program',00h


;========================================================
;数据段定义:占用RAM断(由DATA,IDATA,XDATA指定) 
 rseg  datavar
dummy: ds    1               ;单字节定义 DS


;========================================================
;位地址定义:占用BIT内存断 
 rseg  bitvar
txtbit: dbit  1    


;========================================================      
        end



alien unsigned char asm_sub(void);


main()


{


   asm_sub(4);


}


 


 


4、中断场合



在C程序中使用汇编中断,必须在头文件中给予相应的函数中断入口,其次,在C中要防止入口冲突.


首先掉出启动文件,指定对应的中断入口地址,然后就可以着手了


/************************************************************************
* 2006-7-22 17:18
* 汇编语言中断服务程序
*---------------------------------------------------------
* 文件名:  ASM_INT_PRO
* C语言和汇编语言混合编程,汇编语言中断源程序
************************************************************************/
 NAME     ASM_INT_PRO
   
    public   asm_int                ;interrupt profession
    public   dummy_int              ;dummy_interrupt profession
   
    dummy_int_rountines segment code
    asm_int_rountines   segment code


;========================================================
;dummy-interrupt response
;========================================================
     rseg dummy_int_rountines
dummy_int:
    setb  TR0
 nop
 nop
 reti


;========================================================
;interrupt response 
;========================================================
        rseg asm_int_rountines  
asm_int:                            ;interrupt_rountine entry
    nop
    nop    
    reti
    end


 


============================================================


先到这吧,在外漂了几年了,人也变的浮躁了。坐不住,静不下来了。


还是怀念读大学的时光,至少那时能让自己静下来。但现在。。。难啊。


曾经想重温下校园生涯,蒙头蒙脑又跑回去呆了三年,才发觉一切都变了,一切是


那么让人陌生与恍然。。。


三年后又蒙头蒙脑的跑了出来,又发觉一切也变了。。。


有时总在纳闷,到底是世界变化太快,还是我自己跟不上呢。。。


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)