Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
14.04.2015
Размер:
1.37 Mб
Скачать

Keil Software — Cx51 Compiler User’s Guide

163

 

 

Interfacing C Programs to Assembler

You can easily interface your programs to routines written in 8051 Assembler. The A51 Assembler is an 8051 macro assembler that emits object modules in OMF-51 format. By observing a few programming rules, you can call assembly routines from C and vice versa. Public variables declared in the assembly module are available to your C programs.

There are several reasons to call an assembly routine from your C program.

You may have assembly code already written that you wish to use

You may need to improve the speed of a particular function

You may want to manipulate SFRs or memory-mapped I/O devices directly from assembly

This section describes how to write assembly routines that can be directly interfaced to C programs.

For an assembly routine to be called from C, it must be aware of the parameter passing and return value conventions used in C functions. For all practical purposes, it must appear to be a C function.

Function Parameters

By default, C functions pass up to three parameters in registers. The remaining

parameters are passed in fixed memory locations. You may use the directive 6 NOREGPARMS to disable parameter passing in registers. Parameters are

passed in fixed memory locations if parameter passing in registers is disabled or if there are too many parameters to fit in registers. Functions that pass parameters in registers are flagged by the Cx51 compiler with an underscore character (‘_’) prefixed to the function name at code generation time. Functions that pass parameters only in fixed memory locations are not prefixed with an underscore. Refer to “Using the SRC Directive” on page 166 for an example.

164

Chapter 6. Advanced Programming Techniques

 

 

Parameter Passing in Registers

C functions may pass parameters in registers and fixed memory locations. A maximum of 3 parameters may be passed in registers. All other parameters are passed using fixed memory locations. The following tables define what registers are used for passing parameters.

Arg Number

char, 1-byte ptr

int, 2-byte ptr

long, float

generic ptr

1

R7

R6 & R7

R4—R7

R1—R3

 

 

(MSB in R6,

 

(Mem type in R3,

 

 

LSB in R7)

 

MSB in R2,

 

 

 

 

LSB in R1)

2

R5

R4 & R5

R4—R7

R1—R3

 

 

(MSB in R4,

 

(Mem type in R3,

 

 

LSB in R5)

 

MSB in R2,

 

 

 

 

LSB in R1)

3

R3

R2 & R3

 

R1—R3

 

 

(MSB in R2,

 

(Mem type in R3,

 

 

LSB in R3)

 

MSB in R2,

 

 

 

 

LSB in R1)

The following examples clarify how registers are selected for parameter passing.

 

 

Declaration

Description

 

 

 

 

 

func1 (

The first and only argument, a, is passed in registers R6 and R7.

 

 

 

int a)

 

b,

is passed in registers R6 and R7. The second

 

 

 

func2 (

The first argument,

 

 

 

int b,

argument, c, is passed in registers R4 and R5. The third argument, d, is

 

6

 

 

int c,

passed in registers R1, R2, and R3.

 

 

int *d)

 

e,

is passed in registers R4, R5, R6, and R7. The

 

 

func3 (

The first argument,

 

 

 

long e,

second argument,

f,

cannot be located in registers since those available for

 

 

 

long f)

a second parameter with a type of long are already used by the first argument.

 

 

 

 

This parameter is passed using fixed memory locations.

 

 

 

func4 (

The first argument,

g,

passed in registers R4, R5, R6, and R7. The second

 

 

 

float g,

parameter, h, cannot be passed in registers and is passed in fixed memory

 

 

 

char h)

locations.

 

 

 

 

 

 

 

 

 

 

Keil Software — Cx51 Compiler User’s Guide

165

 

 

Parameter Passing in Fixed Memory Locations

Parameters passed to assembly routines in fixed memory locations use segments named ?function_name?BYTE and ?function_name?BIT to hold the parameter values passed to the function function_name. Bit parameters are copied into the ?function_name?BIT segment prior to calling the function. All other parameters are copied into the ?function_name?BYTE segment. All parameters are assigned space in these segments even if they are passed using registers. Parameters are stored in the order in which they are declared in each respective segment.

The fixed memory locations used for parameter passing may be in internal data memory or external data memory depending upon the memory model used. The SMALL memory model is the most efficient and uses internal data memory for parameter segments. The COMPACT and LARGE models use external data memory for the parameter passing segments.

Function Return Values

Function return values are always passed using CPU registers. The following table lists the possible return types and the registers used for each.

Return Type

Register

Description

 

 

Bit

Carry Flag

Single bit returned in the carry flag

 

 

char / unsigned char,

R7

Single byte typed returned in R7

 

 

1-byte pointer

 

 

 

6

int / unsigned int,

R6 & R7

MSB in R6, LSB in R7

 

2-byte ptr

 

 

 

long / unsigned long

R4-R7

MSB in R4, LSB in R7

 

Float

R4-R7

32-Bit IEEE format

 

 

 

generic pointer

R1-R3

Memory type in R3, MSB R2, LSB R1

 

 

166

Chapter 6. Advanced Programming Techniques

 

 

Using the SRC Directive

The Cx51 compiler can create assembly source files you assemble with the A51 Assembler. These files may be useful when you want to determine the argument passing conventions between C and assembly.

To create an assembly source file, you must use the SRC directive with the Cx51 compiler. For example:

#pragma SRC #pragma SMALL

unsigned int asmfunc1 ( unsigned int arg)

{

return (1 + arg);

}

generates the following assembly output file when compiled using the SRC directive.

; ASM1.SRC generated from: ASM1.C

NAME ASM1

?PR?_asmfunc1?ASM1 SEGMENT CODE

PUBLIC _asmfunc1

;#pragma SRC

;#pragma SMALL

;unsigned int asmfunc1 (

6

RSEG

?PR?_asmfunc1?ASM1

USING

0

_asmfunc1:

 

;---- Variable 'arg?00' assigned to Register 'R6/R7' ----

 

 

; SOURCE LINE # 4

 

 

; SOURCE LINE # 6

 

; return (1 + arg);

 

 

 

; SOURCE LINE # 7

 

MOV

A,R7

 

ADD

A,#01H

 

MOV

R7,A

 

CLR

A

 

ADDC

A,R6

 

MOV

R6,A

; }

; SOURCE LINE # 8

?C0001:

RET ; END OF _asmfunc1

END

Keil Software — Cx51 Compiler User’s Guide

167

 

 

In this example, note that the function name, asmfunc1, is prefixed with an underscore character signifying that arguments are passed in registers. The arg parameter is passed using R6 and R7.

The following example shows the assembly source generated for the same function; however, register parameter passing has been disabled using the

NOREGPARMS directive.

; ASM2.SRC generated from: ASM2.C

NAME

ASM2

 

?PR?asmfunc1?ASM2

SEGMENT CODE

?DT?asmfunc1?ASM2

SEGMENT DATA

PUBLIC

?asmfunc1?BYTE

PUBLIC

asmfunc1

 

RSEG ?DT?asmfunc1?ASM2

?asmfunc1?BYTE:

 

arg?00:

DS 2

;#pragma SRC

;#pragma SMALL

;#pragma NOREGPARMS

;unsigned int asmfunc1 (

RSEG ?PR?asmfunc1?ASM2

USING 0

asmfunc1:

 

 

 

; SOURCE LINE # 5

 

 

; SOURCE LINE # 7

 

; return (1 + arg);

 

 

 

; SOURCE LINE # 8

 

MOV

A,arg?00+01H

 

ADD

A,#01H

6

MOV

R7,A

CLR

A

ADDC

A,arg?00

MOV

R6,A

 

; }

; SOURCE LINE # 9

?C0001:

RET ; END OF asmfunc1

END

Note in this example that the function name, asmfunc1, is not prefixed with an underscore character and that the arg parameter is passed in the

?asmfunc1?BYTE segment.

Соседние файлы в папке HLP