Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

RE: [AVR-Chat] Re: Mixing C and assembly with special requirements.

RE: [AVR-Chat] Re: Mixing C and assembly with special requirements.

2012-03-27 by Tim Mitchell

I'm a bit of an assembly nut and have had good results mixing asm and c. (But not reserving registers, that just ties the compiler in knots)

I create an asm.s file in the project and define any variables I need in one of the c files. Then using .extern in the asm file you can use that variable.

If it's not an assembly routine you pass parameters using register pairs, there is a good AVRGCC help page listing which registers are used.

For example this is a timer interrupt handler for pulse width modulating an RGBW LED in assembler

#include <avr/io.h>

#define xl r26
#define xh r27
#define zl r30
#define zh r31

;timer 2 interrupt handler
.global TIMER2_OVF_vect

.extern RGBW0 ;4 bytes giving RGBW levels - declared globally in a C file
.extern LedPwmct

TIMER2_OVF_vect:
	push zl
	push zh
	in zl,_SFR_IO_ADDR(SREG) ;sreg
	push zl
	push r16
	push r17
	
	;-----led pwm--------------------------
	lds r16,LedPwmct
	dec r16
	sts LedPwmct,r16

	lds r17,LedPwmct
	tst r17
	brne t2_ledpwmnz
	;pwm zero - turn all off
	sbi _SFR_IO_ADDR(PORTB),1
	sbi _SFR_IO_ADDR(PORTB),2
	sbi _SFR_IO_ADDR(PORTB),3
	sbi _SFR_IO_ADDR(PORTD),3
	rjmp t2_ledend

t2_ledpwmnz:
	lds zl,RGBW0
	cp r16,zl
	brsh t2_led_nr
	cbi _SFR_IO_ADDR(PORTB),1
	rjmp t2_led_nro
t2_led_nr:
	sbi _SFR_IO_ADDR(PORTB),1
t2_led_nro:
	lds zl,RGBW0+1
	cp r16,zl
	brsh t2_led_ng
	cbi _SFR_IO_ADDR(PORTB),2
	rjmp t2_led_ngo
t2_led_ng:
	sbi _SFR_IO_ADDR(PORTB),2
t2_led_ngo:
	lds zl,RGBW0+2
	cp r16,zl
	brsh t2_led_nb
	cbi _SFR_IO_ADDR(PORTB),3
	rjmp t2_led_nbo
t2_led_nb:
	sbi _SFR_IO_ADDR(PORTB),3
t2_led_nbo:
	lds zl,RGBW0+3
	cp r16,zl
	brsh t2_led_nw
	cbi _SFR_IO_ADDR(PORTD),3
	rjmp t2_led_nwo
t2_led_nw:
	sbi _SFR_IO_ADDR(PORTD),3
t2_led_nwo:


t2_ledend:
	pop r17
	pop r16
	pop zl
	out _SFR_IO_ADDR(SREG),zl ;sreg
	pop zh
	pop zl
	reti

-- 
Tim Mitchell

Re: Mixing C and assembly with special requirements.

2012-03-28 by Don Kinzer

--- In AVR-Chat@yahoogroups.com, "Steve Hodge" <steve@...> wrote:
> what do you do to pass C arrays and C structs?
The assembly knows nothing about C structures or even simple C types.  Consequently, you have to write the code manually to index arrays and access structure elements.  I've posted a simple example available at the link below.

http://dl.dropbox.com/u/43035239/struct_array.S

If you're going to write C-callable subroutines in assembly language, you'll need to read the avr-libc FAQ entry describing which registers may be modified and which must be preserved.

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage

When you're getting started, it is often helpful to write some equivalent code in C, compile it, and look at the code generated.  That will show you how to define variables in particular memory areas (.bss, .data, .noinit) as well as one way to implement the C logic.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

Re: Mixing C and assembly with special requirements.

2012-03-28 by Don Kinzer

--- In AVR-Chat@yahoogroups.com, "Don Kinzer" <dkinzer@...> wrote:
> I've posted a simple example available at the link below.
After reviewing the example, it will probably be obvious that the structure offset/size definitions for the assembly language code represent a double maintenance issue - if a structure is changed one must remember to update the offset and size definitions.

In our code base we use a special syntax to define structures that contains special tags that are used by an awk script to automatically generate the structure offset and structure size definitions.  The awk script is run (automatically by make) whenever any of the applicable include files is changed thus ensuring that the offset/size information is always current.  The only remaining issue is code that indexes by a structure's size.  To protect against errors arising from structure size changes (and even differences in structure size on different AVR devices, if applicable), we add preprocessor directives to validate the size and issue a compile error if it is unexpected.  An example of this is in the example code I posted.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

RE: [AVR-Chat] Re: Mixing C and assembly with special requirements.

2012-03-28 by Steve Hodge

Tim, this was also very helpful to me also.  Thanks.  Besides plain
variables, what do you do to pass C arrays and C structs?   Steve
Show quoted textHide quoted text
From: AVR-Chat@yahoogroups.com [mailto:AVR-Chat@yahoogroups.com] On Behalf
Of Tim Mitchell
Sent: Tuesday, March 27, 2012 1:51 AM
To: AVR-Chat@yahoogroups.com
Subject: RE: [AVR-Chat] Re: Mixing C and assembly with special requirements.

 

  

I'm a bit of an assembly nut and have had good results mixing asm and c.
(But not reserving registers, that just ties the compiler in knots)

I create an asm.s file in the project and define any variables I need in one
of the c files. Then using .extern in the asm file you can use that
variable.

If it's not an assembly routine you pass parameters using register pairs,
there is a good AVRGCC help page listing which registers are used.

For example this is a timer interrupt handler for pulse width modulating an
RGBW LED in assembler






[Non-text portions of this message have been removed]

RE: [AVR-Chat] Re: Mixing C and assembly with special requirements.

2012-03-28 by Steve Hodge

Thanks a lot for the info, Don.   I'll check it out later today
(side-tracked on something else right now).   Steve
Show quoted textHide quoted text
From: AVR-Chat@yahoogroups.com [mailto:AVR-Chat@yahoogroups.com] On Behalf
Of Don Kinzer
Sent: Wednesday, March 28, 2012 11:33 AM
To: AVR-Chat@yahoogroups.com
Subject: [AVR-Chat] Re: Mixing C and assembly with special requirements.

 

  



--- In AVR-Chat@yahoogroups.com <mailto:AVR-Chat%40yahoogroups.com> , "Don
Kinzer" <dkinzer@...> wrote:
> I've posted a simple example available at the link below.
After reviewing the example, it will probably be obvious that the structure
offset/size definitions for the assembly language code represent a double
maintenance issue - if a structure is changed one must remember to update
the offset and size definitions.

In our code base we use a special syntax to define structures that contains
special tags that are used by an awk script to automatically generate the
structure offset and structure size definitions. The awk script is run
(automatically by make) whenever any of the applicable include files is
changed thus ensuring that the offset/size information is always current.
The only remaining issue is code that indexes by a structure's size. To
protect against errors arising from structure size changes (and even
differences in structure size on different AVR devices, if applicable), we
add preprocessor directives to validate the size and issue a compile error
if it is unexpected. An example of this is in the example code I posted.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net





[Non-text portions of this message have been removed]

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.