Mixing C and Assembly Code with IAR Embedded Workbench™ for FPSLIC™FeaturesIntroductionMixing C and •
Passing Variables between C and This application note describes how to
Assembly Code Functionsuse C to control the program flow and
Assembly•
Calling Assembly Code Functions main program and assembly modules to
from Ccontrol time-critical I/O functions.
•
Calling C Functions from Assembly CodeThe application note also describes how
Application •
Writing Interrupt Functions in to set up and use the IAR C-compiler for
Assembly Codethe FPSLIC controller in projects includ-
•
Accessing Global Variables in ing both C and assembly code. By mix-
NoteAssembly Codeing C and assembly, designers can
c o m b i n e t h e p o w e r f u l C l a n g u a g e
instructions with the effective hardware-
near assembly code instructions.
Table 1. The Pluses and Minuses of C and Assembly
AssemblyC+ Full control of resource usage
+ Efficient code in larger applications
+ Compact/fast code in small applications
+ Structured code
- Inefficient code in larger applications
+ Easy to maintain
- Cryptic code
+ Portable
- Hard to maintain
- Limited control of resource usage
- Non-portable
- Larger/slower code in small applications
Rev. 1976A–11/00
1
Passing Variables between C and Figure 1. Segments in the Register File
Assembly Code FunctionsScratch Register
R0 - R3
When the IAR C-compiler is used for the FPSLIC, the reg-
ister file is segmented as shown in Figure 1.
Scratch registers are not preserved across function calls.
Local Register
R4 - R15
Local registers are preserved across function calls. The Y
register (R28:R29) is used as a data stack pointer to
SRAM. The scratch registers are used for passing parame-
Scratch Register
R16 - R23
ters and return values between functions.
When a function is called, the parameters to be passed to
the function are placed in the register file (registers
Local Register
R24 - R27
R16 - R23). When a function is returning a value, this value
is placed in the register file (registers R16 - R19), depend-
ing on the size of the parameters and the returned value.
Data Stack Pointers (Y)
R28 - R29
Table 2 shows example placement of parameters when
Scratch Register
R30 - R31
calling a function.
Table 2. Placement and Parameters of C Functions
FunctionParameter 1 RegistersParameter 2 Registersfunc (char, char)
R16
R20
func (char, int)
R16
R20, R21
func (int, long)
R16, R17
R20, R21, R22, R23
func (long, long)
R16, R17, R18, R19
R20, R21, R22, R23
For a complete reference of the supported data types and
If a function is called with more than two parameters, the
cor responding sizes, see the
AVR ®
IAR Co mp ilerfirst two parameters are passed to the function as shown
Reference Guide from IAR Systems, Data Representation
above. The remaining parameters are passed to the func-
section.
tion on the data stack. If a function is called with a
struct or
Example C function call:
union as a parameter, a pointer to the structure is passed
on to the function on the data stack.
int get_port(unsigned char temp, int num)
When calling this C function, the 1-byte parameter
temp is
If a function needs to use any local registers, it first pushes
placed in R16 and the 2-byte parameter
num is placed in
the registers on the data stack. Then the return value from
R20:R21. The function returns a 2-byte value, which is
the function is placed at addresses R16 - R19, depending
placed in R16:R17 after return from the function.
on the size of the returned value.
2FPSLIC
FPSLICExample 1Calling Assembly Code Functions from a C Program – with No Parameters and No
Return ValueExample C Code for Calling Assembly Code Function#include "ioat94k.h"
extern void get_port(void);/* Function prototype for asm function */
void main(void)
{
DDRD = 0x00;
/* Initialization of the I/O ports */
DDRE = 0xFF;
while(1)
/* Infinite loop
*/
{
get_port();
/* Call the assembler function
*/
}
}
The Called Assembly Code FunctionNAME get_port
#include "ioat94k.h"
; The #include file must be within the module
PUBLIC get_port
; Declare symbols to be exported to C function
RSEG CODE
; This code is relocatable, RSEG
get_port;
; Label, start execution here
in R16,PIND
; Read in the pind value
swap R16
; Swap the upper and lower nibble
out PORTE,R16
; Output the data to the port register
ret
; Return to the main function
END
3
Calling Assembly Code Functions from a C Function – Passing Parameters and
Returning Values
This example C function is calling an assembler function.
The assembly function is returning a value in R16 to the C
The 1-byte
mask is passed as a parameter to the assem-
variable
value.
bly function;
mask is placed in R16 before the function call.
#include "ioat94k.h"
char get_port(char mask);
/*Function prototype for asm function */
void C_task main(void)
{
DDRE=0xFF
while(1)
/* Infinite loop*/
{
char value, temp;
/* Decalre local variables*/
temp = 0x0F;
value = get_port(temp); /* Call the assembler function */
if(value==0x01)
{
/* Do something if value is 0x01 */
PORTE=~(PORTE);
/* Invert value on Port E */
}
}
}
The Called Assembly Code FunctionNAME get_port
#include "ioat94k.h"
; The #include file must be within the module
PUBLIC get_port
; Symbols to be exported to C function
RSEG CODE
; This code is relocatable, RSEG
get_port:
; Label, start execution here
in
R17,PIND
; Read in the pind value
eor
R16,R17
; XOR value with mask(in R16) from main()
swap R16
; Swap the upper and lower nibble
rol
R16
; Rotate R16 to the left
brcc ret0
; Jump if the carry flag is cleared
ldi
r16,0x01
; Load 1 into R16, return value
ret
; Return
ret0: clr
R16
; Load 0 into R16, return value
ret
; Return
END
4FPSLIC
FPSLICCalling C Functions from Assembly Code
Assuming that the assembly function calls the standard C
(16 bits). This example writes only the lower byte/8 bits to
library routine rand() to get a random number to output
a port.
to the port. The rand() routine returns an integer value
NAME get_port
#include "ioat94k.h"
; The #include file must be within the module
EXTERN rand, max_val
; External symbols used in the function
PUBLIC get_port
; Symbols to be exported to C function
RSEG CODE
; This code is relocatable, RSEG
get_port:
; Label, start execution here
clr
R16
; Clear R16
sbis
PIND,0
; Test if PIND0 is 0
rcall
rand
; Call RAND() if PIND0 = 0
out
PORTE,R16
; Output random value to PORTE
lds
R17,max_val
; Load the global variable max_val
cp
R17,R16
; Check if number higher than max_val
brlt
nostore
; Skip if not
sts
max_val,R16
; Store the new number if it is higher
nostore:
ret
; Return
END
5
Writing Interrupt Functions in Assembly
Interrupt functions can be written in assembly. Interrupt
Care must be taken to avoid problems with the interrupt
functions cannot have any parameters or return any value.
functions in C when assembler code is placed at the inter-
Because an interrupt can occur anywhere in the program
rupt vector addresses.
execution, it needs to store all used registers on the stack.
Example Code Placed at Interrupt VectorNAME EXT_INT1
#include "ioat94k.h"
extern c_int1
COMMON INTVEC(1)
; Code in interrupt vector segment
ORG INT1_vect
; Place code at interrupt vector
RJMP
c_int1
; Jump to assembler interrupt function
ENDMOD
;The interrupt vector code performs a jump to the function c_int1:
NAME c_int1
#include "ioat94k.h"
PUBLIC c_int1
; Symbols to be exported to C function
RSEG CODE
; This code is relocatable, RSEG
c_int1:
st
-Y,R16
; Push used registers on stack
in
R16,SREG
; Read status register
st
-Y,R16
; Push Status register
in
R16,PIND
; Load in value from port D
com
R16
; Invert it
out
PORTE,R16
; Output inverted value to port E
ld
R16,Y+
; Pop status register
out
SREG,R16
; Store status register
ld
R16,Y+
; Pop Register R16
reti
END
6FPSLIC
FPSLICAccessing Global Variables in Assembly
The main program introduces a global variable called
variable, the assembly function uses LDS (Load Direct
max_val. To access this variable in assembly, the variable
from SRAM) and STS (STore Direct to SRAM) instructions.
must be declared as
EXTERN max_val. To access the
#include "ioat94k.h"
char max_val;
void get_port(void);
/* Function prototype for assembler function */
void C_task main(void)
{
DDRE = 0xFF;
/* Set port E as output */
while(1)
/* Infinite loop */
{
get_port();
/* Call assembly code function */
}
}
NAME get_port
#include "ioat94k.h"
; The #include file must be within the module
EXTERN rand, max_val
; External symbols used in the function
PUBLIC get_port
; Symbols to be exported to C function
RSEG CODE
; This code is relocatable, RSEG
get_port:
; Label, start execution here
clr
R16
; Clear R16
sbis
PIND,0
; Test if PIND0 is 0
rcall
rand
; Call RAND() if PIND0 = 0
out
PORTE,R16
; Output random value to PORTE
lds
R17,max_val
; Load the global variable max_val
cp
R17,R16
; Check if number higher than max_val
brlt
nostore
; Skip if not
sts
max_val,R16
; Store the new number if it is higher
nostore:
ret
; Return
END
References
AVR®
IAR Compiler Reference Guide from IAR Systems
7
Atmel HeadquartersAtmel OperationsCorporate HeadquartersAtmel Colorado Springs2325 Orchard Parkway
1150 E. Cheyenne Mtn. Blvd.
San Jose, CA 95131
Colorado Springs, CO 80906
TEL (408) 441-0311
TEL (719) 576-3300
FAX (408) 487-2600
FAX (719) 540-1759
EuropeAtmel RoussetAtmel SarL
Zone Industrielle
Route des Arsenaux 41
13106 Rousset Cedex
Casa Postale 80
France
CH-1705 Fribourg
TEL (33) 4-4253-6000
Switzerland
FAX (33) 4-4253-6001
TEL (41) 26-426-5555
FAX (41) 26-426-5500
Atmel Smart Card ICsScottish Enterprise Technology Park
AsiaEast Kilbride, Scotland G75 0QR
Atmel Asia, Ltd.
TEL (44) 1355-803-000
Room 1219
FAX (44) 1355-242-743
Chinachem Golden Plaza
77 Mody Road Tsimhatsui
Atmel GrenobleEast Kowloon
Avenue de Rochepleine
Hong Kong
BP 123
TEL (852) 2721-9778
38521 Saint-Egreve Cedex
FAX (852) 2722-1369
France
TEL (33) 4-7658-3000
JapanFAX (33) 4-7658-3480
Atmel Japan K.K.
9F, Tonetsu Shinkawa Bldg.
1-24-8 Shinkawa
Chuo-ku, Tokyo 104-0033
Japan
TEL (81) 3-3523-3551
FAX (81) 3-3523-7581
Atmel FPSLIC HotlineFax-on-Demand1-(408) 436-4119
North America:
1-(800) 292-8635
Atmel FPSLIC e-mailInternational:
fpslic@atmel.com
1-(408) 441-0732
FAQ
Available from Website
e-mail
literature@atmel.com
Web Site
http://www.atmel.com
BBS
1-(408) 436-4309
© Atmel Corporation 2000.
Atmel Corporation makes no warranty for the use of its products, other than those expressly contained in the Company’s standard war-
ranty which is detailed in Atmel’s Terms and Conditions located on the Company’s web site. The Company assumes no responsibility for
any errors which may appear in this document, reserves the right to change devices or specifications detailed herein at any time without
notice, and does not make any commitment to update the information contained herein. No licenses to patents or other intellectual prop-
erty of Atmel are granted by the Company in connection with the sale of Atmel products, expressly or by implication. Atmel’s products are
not authorized for use as critical components in life suppor t devices or systems.
Marks bearing ® and/or ™ are registered trademarks and trademarks of Atmel Corporation.
Printed on recycled paper.
Terms and product names in this document may be trademarks of others.
1976A–11/00/xM
Document Outline
- Features
- Introduction
- Passing Variables between C and Assembly Code Functions
- Example 1
- Calling Assembly Code Functions from a C Program
with No Parameters and No Return Value
- Example C Code for Calling Assembly Code Function
- The Called Assembly Code Function
- Calling Assembly Code Functions from a C Function
Passing Parameters and ReturningValues
- The Called Assembly Code Function
- Calling C Functions from Assembly Code
- Writing Interrupt Functions in Assembly
- Example Code Placed at Interrupt Vector
- Accessing Global Variables in Assembly
- References
Add New Comment