|
|
View previous topic :: View next topic |
Author |
Message |
mcb Guest
|
trouble with #inline directive |
Posted: Thu Mar 01, 2007 3:45 pm |
|
|
this is my c code
Code: | #include <16f84.h>
#device *=16
#FUSES NOWDT,hs,NOPUT,NOPROTECT//,NOBROWNOUT,NOCPD,NOLVP,NOCPD,//MCLR
#build(reset = 0x30, interrupt = 0x34)
#org 0, 0x2f {}
int zc;
#locate zc=17
int cb;
#locate cb=18
int rdon[58];
#inline
turbo()
{
cb = cb*10;
zc = zc*80;
cb=cb+3;
}
#org 0x36 , 0x85
main()
{
turbo();
}
#ORG default |
and this is the disassembled ccs c hex code
Code: |
; Generated by WinDis84, (c) Nigel Goodwin 1998.
LIST P=16F84, F=INHX8M
include "P16FXX.inc"
ORG 0x0000
ORG 0x0030
MOVLW 0x00
MOVWF PCLATH
GOTO Label_0001
NOP
ORG 0x0036
Label_0001 CLRF FSR
BCF STATUS , IRP
MOVLW 0x1F
ANDWF STATUS , f
MOVF 0x13 , W
MOVWF 0x4E
MOVLW 0x0A
MOVWF 0x4F
CALL Label_0002
MOVF 0x0D , W
MOVWF 0x13
MOVF 0x12 , W
MOVWF 0x4E
MOVLW 0x50
MOVWF 0x4F
CALL Label_0002
MOVF 0x0D , W
MOVWF 0x12
MOVLW 0x03
ADDWF 0x13 , f
SLEEP
ORG 0x0086
Label_0002 CLRF 0x0C
CLRF 0x0D
MOVF 0x4E , W
BCF STATUS , C
BTFSC 0x4F , 00
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 01
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 02
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 03
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 04
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 05
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 06
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4F , 07
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
RETLW 0x00
|
Code: | ORG 0x0086
Label_0002 CLRF 0x0C | there is something wrong...
but if i would write only cb++; or cb--; rather than cb=cb+1; or cb=cb-1; it will be ok.why? what is the difference between two code for inlining. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 01, 2007 4:22 pm |
|
|
The compiler is calling the CCS 8-bit multiplication routines, which
are located at address 0x86.
To prevent it from calling those routines, you could substitute your
own code to do the multiplication. You can multiply by 10 or
multiply by 80 by doing a sequence of shifts and adds. |
|
|
mcb Guest
|
|
Posted: Thu Mar 01, 2007 4:45 pm |
|
|
why does compiler use this method? is there any way to use these multiplication routines without calling any subroutine.i dont wanna write my own code , at least i will copy multiplication section below org 0x86 and use them with #asm-endasm.but i hope they will fix or add new directive to use embeded routines with inline.
thank you very much. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Mar 01, 2007 5:29 pm |
|
|
Just curious, but why do you care so much? Your workaround by copying the assembly code is a lot of work and looks ugly and that only for saving a few bytes and neglectable speed gain.
If speed and code size are that important to you than follow PCM's suggestion and rewrite the multiplications by a combination of shift and add instructions.
Code: | #inline turbo()
{
// cb = cb * 10;
// cb = cb * (8 + 2);
cb = cb<<3 + cb<<1;
// zc = zc * 80;
// zc = zc * (64 + 16);
zc = zc<<6 + zc<<4;
cb=cb+3;
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 01, 2007 5:30 pm |
|
|
I would have told him that, but he didn't want to write any code so I bailed. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Mar 01, 2007 6:01 pm |
|
|
Hi PCM,
I know you would have helped him if he wanted to write the code. It's just that I was curious why someone would go into all this trouble of copying asm code and I hope mcb will return to enlighten us.
Posting this question I decided to write the example code as an exercise for myself. I'm glad to be using PIC18 processors with hardware multiplier. |
|
|
mcb Guest
|
|
Posted: Fri Mar 02, 2007 2:40 am |
|
|
hi all, that is my example code on 16f84.i m trying to understand behaviour of compiler.i will write a program like a bootloader so i wanna get full of control over system as possible as with minimum asm code.
but i cant locate some code part like this.i have one more problem which is ccs c multiplication routines dont obey #org directives. my own subroutine ,turbo(), is on the correct location but it calls multiplication routines from prevented area.
Code: | #include <16f84.h>
#device *=16
#FUSES NOWDT,hs,NOPUT,NOPROTECT//,NOBROWNOUT,NOCPD,NOLVP,NOCPD,//MCLR
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_a0, rcv=PIN_a1)
#define status 0x03
#define c 0x00
#define f 0x00
#define w 0x00
#build(reset = 0x30, interrupt = 0x34)
#org 0, 0x2f {}
#org 0x96,0x3fe{}
int zc;
#locate zc = 0x11
int cb;
#locate cb = 0x12
int rdon[55];
#locate rdon=0x13
#org 0x86 , 0x95
void turbo()
{
cb = cb*22;
}
#org 0x36 , 0x85
main()
{
zc=1;
cb=2;
turbo();
rdon[0]=1;
rdon[54]=2;
}
#ORG default
|
and this is result.
Code: | ORG 0x0000
Label_0004 CLRF 0x0C
CLRF 0x0D
MOVF 0x4B , W
BCF STATUS , C
BTFSC 0x4C , 00
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 01
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 02
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 03
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 04
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 05
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 06
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
BTFSC 0x4C , 07
ADDWF 0x0C , f
RRF 0x0C , f
RRF 0x0D , f
GOTO Label_0001
ORG 0x0030
MOVLW 0x00
MOVWF PCLATH
GOTO Label_0002
NOP
ORG 0x0036
Label_0002 CLRF FSR
BCF STATUS , IRP
MOVLW 0x1F
ANDWF STATUS , f
BSF STATUS , RP0
BCF TRISA , 00
BCF STATUS , RP0
BSF PORTA , 00
MOVLW 0x01
MOVWF 0x11
MOVLW 0x02
MOVWF 0x12
CALL Label_0003
MOVLW 0x01
MOVWF 0x13
MOVLW 0x02
MOVWF 0x49
SLEEP
ORG 0x0086
Label_0003 MOVF 0x12 , W
MOVWF 0x4B
MOVLW 0x16
MOVWF 0x4C
GOTO Label_0004
Label_0001 MOVF 0x0D , W
MOVWF 0x12
RETLW 0x00
|
there is enought rom between (0x36 , 0x85) but compiler dont locate multiplication routines there.it choses different location where is prevented by org directive.
this is just a example , my own code is larger so i must solve these memory - ram problems.
thank you all |
|
|
mcb Guest
|
|
Posted: Fri Mar 02, 2007 2:57 am |
|
|
this is more clear Code: | #include <16f84.h>
#device *=16
#FUSES NOWDT,hs,NOPUT,NOPROTECT//,NOBROWNOUT,NOCPD,NOLVP,NOCPD,//MCLR
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_a0, rcv=PIN_a1)
#define status 0x03
#define c 0x00
#define f 0x00
#define w 0x00
#build(reset = 0x30, interrupt = 0x34)
#org 0, 0x2f {}
#org 0x106,0x3ff{}
int zc;
#locate zc = 0x11
int cb;
#locate cb = 0x12
int rdon[55];
#locate rdon=0x13
#org 0x35 , 0x105
main()
{
zc=1;
cb=2;
cb = cb*15;
rdon[0]=1;
rdon[54]=2;
}
#ORG default |
Code: | ORG 0x0000
ORG 0x0030
MOVLW 0x00
MOVWF PCLATH
GOTO Label_0001
NOP
ORG 0x0035
Label_0001 CLRF FSR
BCF STATUS , IRP
MOVLW 0x1F
ANDWF STATUS , f
BSF STATUS , RP0
BCF TRISA , 00
BCF STATUS , RP0
BSF PORTA , 00
MOVLW 0x01
MOVWF 0x11
MOVLW 0x02
MOVWF 0x12
MOVF 0x12 , W
MOVWF 0x4B
MOVLW 0x0F
MOVWF 0x4C
GOTO Label_0002
MOVF 0x0D , W
MOVWF 0x12
MOVLW 0x01
MOVWF 0x13
MOVLW 0x02
MOVWF 0x49
SLEEP
ORG 0x03FF
Label_0002 CLRF 0x0C |
and there is no multiplication routines correctly.i think compiler wanna its own location, and wont locate multiplication routines in main function |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 02, 2007 3:28 am |
|
|
Hint. This is what the 'default' keyword does. This forces 'system' routines to be placed in the area.
If you declare your code as:
Code: |
org 0x36, 0x85 default
#inline
void turbo(void) {
cb = cb*10;
zc = zc*80;
cb=cb+3;
}
void main(void) {
turbo();
}
|
With the other declarations obviously, then the 'main', and the functions called 'inline', together with 'turbo', will all be placed in the required area. You can also use a #org, with a different range, and a 'default' keyword, to force the maths routines alone to be relocated, using:
Code: |
#org 0x60, 0x85 default
#inline
void turbo(void) {
cb = cb*10;
zc = zc*80;
cb=cb+3;
}
#org 0x35, 0x5F
void main(void) {
turbo();
}
#org default
|
The 'turbo' routine, is flagged as 'inline', so does not itself get put at 0x60, but the _maths_ routines it calls, are located here.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Mar 02, 2007 3:48 am |
|
|
Just a remark: in CCS it is very unusual to have this many #org statements, it now looks like you are rewriting code originally designed for another compiler. In many other PIC compilers you have to specify the addresses for variables but the CCS compiler is more smart in this respect; you specify the memory range and then have the CCS compiler decide where to put everything. The advantage of giving control to the CCS compiler is that the compiler can re-use RAM as often as it can and you won't run into problems with new compiler versions which are 'improved' and have other memory requirements.
I get the idea you are putting way to much effort in saving a few bytes and you are missing the larger picture. If this is a new design, choose a PIC with more memory as that will turn out to be much cheaper. If you are upgrading an existing project than reconsider another bootloader approach, for example the Tiny Bootloader is very small and proven code. |
|
|
mcb Guest
|
|
Posted: Fri Mar 02, 2007 1:03 pm |
|
|
Ttelmah thank you for your good expressions,i understand that compiler make a multiplication subroutine and uses it for different variables.this is very good.i will use "default" directive .this is very useful.
thank you all |
|
|
3dfx
Joined: 24 Mar 2007 Posts: 6
|
|
Posted: Sun Apr 01, 2007 11:20 am |
|
|
hi,is there any way to using #inline directive with #asm directive?
Code: |
#inline
void goto_xy(int x)
{
#locate x = ram_location
#asm
call rom_adress
#endasm
}
|
this is the result ;
Code: |
.................... goto_xy(0x10);
006D: MOVLW 10
006E: MOVWF 21
|
compiler pass asm codes. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|