testcode 发表于 2005-3-19 01:14:02

如何在CVAVR中嵌入汇编?C和汇编之间的参数调用方法,以及注意点如何?

久没用做作业了,马老师布置的作业就尽量做好, 争取做个好学生。



1.在CVAVR中嵌入汇编的一般格式:

#asm

….

….

Assembly language code

….

….

#endasm



2.在CVAVR中嵌入汇编时寄存器的使用注意事项:

尽量使用R4到R20这17个寄存器。其他的15个寄存器CVAVR编译器可能有其他用途,如中断等。



3.明确定义寄存器的地址:

即 .equ 语句

例如:即使已经有

#include <mega162.h>,但sfrb的说明对汇编不起作用。

在汇编中仍然要:

#asm

….

.equ PORTB= $17

.equ PIND= $….

….

out PORTB,r16

….

#endasm



4.汇编中的标签的第一个字符避免使用下划线。

例如,以下要尽量避免使用

_delay:

    push r16

machao 发表于 2005-3-19 01:16:25

非常好!
-----此内容被machao于2005-03-19,01:58:27编辑过

testcode 发表于 2005-3-19 01:16:35

5.汇编调入C参数的方法:

函数中参数的值调入汇编存放在数据栈中的次序:

例如:

#pragma warn- // this will prevent warnings

int sum_abc(int a, int b, unsigned char c){

#asm

    ldd   r30,y+3 ;R30=LSB a

    ldd   r31,y+4 ;R31=MSB a

    ldd   r26,y+1 ;R26=LSB b

    ldd   r27,y+2 ;R27=MSB b

    add   r30,r26 ;(R31,R30)=a+b

    adc   r31,r27

    ld    r26,y   ;R26=c

    clr   r27   ;promote unsigned char c to int

    add   r30,r26 ;(R31,R30)=(R31,R30)+c

    adc   r31,r27

#endasm

}

#pragma warn+ // enable warnings

编译器先把a放入数据栈,然后是b, 最后是c。每推入一个参数,Y值递减相应的字节。

例如整数a,b各占两个字节,c占一个字节。

对于多字符的数据,先放入MSB,然后LSB。



6.汇编函数返回参数到C的方法:

将要返回的参数存储到以下寄存器中

   R30 存放字符

   R30, R31 存放整型

   R30, R31, R22, R23存放长整型.

例如:

unsigned long int number;

unsigned long int IncLong(unsigned long int n);



void main(void)

{

number = 1234567;

number = IncLong(number);

while (1);

}



#pragma warnunsigned

long int IncLong(unsigned long int i)

{

#asm

;

; 数据栈如下:

;

; MSB

; 2nd MSB

; 3rd MSB

; LSB <- Y

;

; Y 转向LSB

;

ldd r23,y+3 ; get MSB into r23

ldd r22,y+2 ; next into r22

ldd r31,y+1 ; next into r31

ld r30,y ; least into r30

inc r30 ; increment LSB

brne done_IncLong

inc r31

brne done_IncLong

inc r22

brne done_IncLong

inc r23

done_IncLong:

;

; 因为结果已经存放在适当的寄存器上,R30, R31, R22, R23

; 可以直接返回

;

#endasm

}

#pragma warn+



7.全局变量的调用:

有全局变量如下:

char temp;

unsigned int value;

CVAVR在自生成汇编时,在SRAM中预存空间,并且用同样的变量名字,除了在变量名字前加入一个下划线,

即生成_temp以及 _value的变量名字。

所以可以用以下方法直接调用:

lds r17, _ch

sts _value+1, r17

调用时注意多字节的数据的存放次序是:

先LSB存放在低位,然后MSB存放在高位。



Reference:

1. CodeVisionAvr User Manual;

2. CodeVision C Tutorial;

yinhe 发表于 2008-5-15 15:36:47

记号
页: [1]
查看完整版本: 如何在CVAVR中嵌入汇编?C和汇编之间的参数调用方法,以及注意点如何?