Simple example of changes to typical heartbeat timer irq inline assembly

Original C18 Code

	_asm
	//Reset timer for next rollover
	movff	TMR0L,uc_asm_irq_temp			//read_current_timer_value (read low byte loads high byte)
	movff	TMR0H,uc_asm_irq_temp1
	movlw	0xbb
	addwf	uc_asm_irq_temp,1,0				//(1 = file register, 0 = access ram)
	movlw	0x3c
	addwfc	uc_asm_irq_temp1,1,0			//(1 = file register, 0 = access ram)
	movff	uc_asm_irq_temp1,TMR0H			//Store new value (high byte first)
	movff	uc_asm_irq_temp,TMR0L
	_endasm
Newer XC Code

IMPORTANT – MAKE SURE XC8 OPTIMIZATIONS 'ADDRESS QUALIFIERS' IS SET TO 'REQUIRE' 


	#asm
	GLOBAL _uc_asm_irq_temp
	GLOBAL _uc_asm_irq_temp1
	//Reset timer for next rollover
	movff	TMR0L,_uc_asm_irq_temp			//read_current_timer_value (read low byte loads high byte)
	movff	TMR0H,_uc_asm_irq_temp1
	movlw	0xfb
	addwf	_uc_asm_irq_temp,f,c				//(f = file register, c = common/access ram)
	movlw	0xd8
	addwfc	_uc_asm_irq_temp1,f,c			//(f = file register, c = common/access ram)
	movff	_uc_asm_irq_temp1,TMR0H			//Store new value (high byte first)
	movff	_uc_asm_irq_temp,TMR0L
	#endasm

What changed:

_asm and _endasm change to #asm and #endasm
Variables are declared in C without a leading underscore, but to be used in assembler code they must have a leading underscore added and be declared using GLOBAL.

Previous XC Code

Newer versions of XC8 generate a "error: (876) syntax error" to the use of the below. It turns out ",1,0" on the end of the addwf and addwfc lines are the issue (even though these numeric values are specified for use in device datasheets).  

The '1' needs to change to 'f' for file register.

The '0' needs to change to 'c' for common memory / access ram (the alternative would be 'b' for bank select register).

IMPORTANT – MAKE SURE XC8 OPTIMIZATIONS 'ADDRESS QUALIFIERS' IS SET TO 'REQUIRE' 


	#asm
	GLOBAL _uc_asm_irq_temp
	GLOBAL _uc_asm_irq_temp1
	//Reset timer for next rollover
	movff	TMR0L,_uc_asm_irq_temp			//read_current_timer_value (read low byte loads high byte)
	movff	TMR0H,_uc_asm_irq_temp1
	movlw	0xbb
	addwf	_uc_asm_irq_temp,1,0				//(1 = file register, 0 = access ram)
	movlw	0x3c
	addwfc	_uc_asm_irq_temp1,1,0			//(1 = file register, 0 = access ram)
	movff	_uc_asm_irq_temp1,TMR0H			//Store new value (high byte first)
	movff	_uc_asm_irq_temp,TMR0L
	#endasm

 

For more information see the "C18 to XC8 C Compiler Migration Guide" as there are some key differences

Instruction Arguments

Destination select bit

w = store result in WREG (0)
f = store result in file register f (1)

RAM access bit

c = common / access ram (0)
b = bank select register (1)

 

USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.