|
|
View previous topic :: View next topic |
Author |
Message |
Felo
Joined: 23 May 2020 Posts: 7
|
inline function |
Posted: Mon Jan 25, 2021 2:20 pm |
|
|
Question:
What is the code that the compiler generates for inline functions used for?
Question details: I don't understand what the code generated by the compiler at addresses 00040 to 00044 of the following .lst file is used for
Compiler version: 5.015
lst file
00014 .................... #device PIC18F46K22
00015 ....................
01019 .................... #list
01020 ....................
01021 .................... #device ADC=16
01022 ....................
01023 .................... #FUSES NOWDT //No Watch Dog Timer
01024 .................... #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
01025 .................... #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
01026 ....................
01027 .................... #use delay(crystal=20000000)
01028 ....................
01029 ....................
01030 .................... #pragma inline
01031 ....................
01032 .................... int suma(int a, int b) {
01033 .................... return (a +b);
00040 5009 01034 MOVF 09,W
00042 2408 01035 ADDWF 08,W
00044 6E01 01036 MOVWF 01
01037 .................... }
01038 ....................
01039 .................... void main(void){
00004 6AF8 01040 CLRF FF8
00006 9ED0 01041 BCF FD0.7
00008 50C1 01042 MOVF FC1,W
0000A 0BF0 01043 ANDLW F0
0000C 6EC1 01044 MOVWF FC1
0000E 0E00 01045 MOVLW 00
00010 010F 01046 MOVLB F
00012 6F38 01047 MOVWF x38
00014 6F3C 01048 MOVWF x3C
00016 6F39 01049 MOVWF x39
00018 6F3A 01050 MOVWF x3A
0001A 6F3B 01051 MOVWF x3B
0001C 0101 01052 MOVLB 1
0001E 6B88 01053 CLRF x88
00020 6A77 01054 CLRF F77
00022 6A78 01055 CLRF F78
00024 6A79 01056 CLRF F79
00026 6A05 01057 CLRF 05
01058 .................... int c =0;
01059 .................... for (int i=0;i<4;i++)
00028 6A06 01060 CLRF 06
0002A 5006 01061 MOVF 06,W
0002C 0803 01062 SUBLW 03
0002E E311 01063 BNC 0052
01064 .................... for (int k=0;k < 3;k++)
00030 6A07 01065 CLRF 07
00032 5007 01066 MOVF 07,W
00034 0802 01067 SUBLW 02
00036 E30B 01068 BNC 004E
01069 .................... c = suma(i,k);
00038 C006 F008 01070 MOVFF 06,08
0003C C007 F009 01071 MOVFF 07,09
00046 C001 F005 01072 MOVFF 01,05
0004A 2A07 01073 INCF 07,F
0004C D7F2 01074 BRA 0032
0004E 2A06 01075 INCF 06,F
00050 D7EC 01076 BRA 002A
01077 ....................
01078 ....................
01079 .................... }
00052 0003 1080 SLEEP
Thanks
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 25, 2021 2:46 pm |
|
|
The suma() function adds two numbers and returns the result.
Code: | int suma(int a, int b) {
return (a +b);
} |
It's put "inline" to eliminate the need for CALL and RETURN instructions.
This reason for this could be to increase the speed of execution or to
reduce the amount of flash memory used for the program. |
|
|
Felo
Joined: 23 May 2020 Posts: 7
|
inline function |
Posted: Mon Jan 25, 2021 3:00 pm |
|
|
PCM programmer wrote: | The suma() function adds two numbers and returns the result.
Code: | int suma(int a, int b) {
return (a +b);
} |
It's put "inline" to eliminate the need for CALL and RETURN instructions.
This reason for this could be to increase the speed of execution or to
reduce the amount of flash memory used for the program. |
In my case I use inline because I want the function code to be generated in different memory areas.
I do not understand why the compiler generates the code that I indicate in the post.
Thanks for answering |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 25, 2021 3:09 pm |
|
|
Does that mean you still need an answer ? Your question was:
Quote: |
I don't understand what the code generated by the compiler at addresses
00040 to 00044 of the following .lst file is used for. |
00040 to 00044 is the following code:
Quote: | 01032 .................... int suma(int a, int b) {
01033 .................... return (a +b);
00040 5009 01034 MOVF 09,W
00042 2408 01035 ADDWF 08,W
00044 6E01 01036 MOVWF 01
01037 .................... } |
It's used to add two numbers and give back the result.
If your question is really "What does the entire program do ?", then post a
link to the entire program so we can look at it. |
|
|
Felo
Joined: 23 May 2020 Posts: 7
|
inline function |
Posted: Mon Jan 25, 2021 3:16 pm |
|
|
PCM programmer wrote: | Does that mean you still need an answer ? Your question was:
Quote: |
I don't understand what the code generated by the compiler at addresses
00040 to 00044 of the following .lst file is used for. |
00040 to 00044 is the following code:
Quote: | 01032 .................... int suma(int a, int b) {
01033 .................... return (a +b);
00040 5009 01034 MOVF 09,W
00042 2408 01035 ADDWF 08,W
00044 6E01 01036 MOVWF 01
01037 .................... } |
It's used to add two numbers and give back the result.
If your question is really "What does the entire program do ?", then post a
link to the entire program so we can look at it. |
The program is trivial. It works perfectly. The question is about the compiler.
However I annex the program.
Thank you.
Program:
#include <inlineTest.h>
#pragma inline
int suma(int a, int b) {
return (a +b);
}
void main(void){
int c =0;
for (int i=0;i<4;i++)
for (int k=0;k < 3;k++)
c = suma(i,k);
} |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19559
|
|
Posted: Tue Jan 26, 2021 12:53 am |
|
|
If you look at your original listing, and then 'reorder' based on the actual
memory address, you have (comments inline):
Code: |
01069 .................... c = suma(i,k);
00038 C006 F008 01070 MOVFF 06,08 //Move the two values
0003C C007 F009 01071 MOVFF 07,09 //to the working registers
//The suma function code is at address 0040
00040 5009 01034 MOVF 09,W
00042 2408 01035 ADDWF 08,W //add the values
00044 6E01 01036 MOVWF 01
00046 C001 F005 01072 MOVFF 01,05 //move the result to final location
|
Though the code is 'shown', where is is declared, the physical assembly
code has been placed 'inside' the main function where it is called. Hence
'inline'.
Now with the 'inline' function, if you called it multiple times, the listing
below the actual declaration, would show a new copy for every place
it was called, with the addresses being those for the location where it
was 'called'.
The assembler just happens to always display the code where it is declared,
not repositioning it to where it is used. You have to solve this yourself. |
|
|
Felo
Joined: 23 May 2020 Posts: 7
|
IMHO it is very poor code generation. |
Posted: Tue Jan 26, 2021 2:21 am |
|
|
Hi Ttelmah:
IMHO it is very poor code generation.
Even when the function is called more than once, the code in the function declaration is generated as many times as it is called in the program as can be seen in this other example. This useless code consumes memory since it not only appears in the list, it is also in the .hex file.
Thank you for your prompt and effective response.
Kind Regards
MPASM
CCS PCH C Compiler, Version 5.015, xxxx 26-Jan-21 02:48
Filename: D:\SoftIOM\inlineTest.lst
ROM used: 144 bytes (0%)
Largest free fragment is 65392
RAM used: 5 (0%) at main() level
9 (0%) worst case
Stack used: 0 locations
Stack size: 31
00000 EF02 F000 00001 GOTO 0004
00002 .................... #include <inlineTest.h>
00003 .................... #include <18F46k22.h>
00004 .................... //////////// Standard Header file for the PIC18F46K22 device ////////////////
00005 .................... ///////////////////////////////////////////////////////////////////////////
00006 .................... //// (C) Copyright 1996, 2013 Custom Computer Services ////
00007 .................... //// This source code may only be used by licensed users of the CCS C ////
00008 .................... //// compiler. This source code may only be distributed to other ////
00009 .................... //// licensed users of the CCS C compiler. No other use, reproduction ////
00010 .................... //// or distribution is permitted without written permission. ////
00011 .................... //// Derivative programs created using this software in object code ////
00012 .................... //// form are not restricted in any way. ////
00013 .................... ///////////////////////////////////////////////////////////////////////////
00014 .................... #device PIC18F46K22
00015 ....................
01019 .................... #list
01020 ....................
01021 .................... #device ADC=16
01022 ....................
01023 .................... #FUSES NOWDT //No Watch Dog Timer
01024 .................... #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
01025 .................... #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
01026 ....................
01027 .................... #use delay(crystal=20000000)
01028 ....................
01029 ....................
01030 .................... #pragma inline
01031 ....................
01032 .................... int suma(int a, int b) {
01033 .................... return (a +b);
00040 5009 01034 MOVF 09,W // (Observe how the code in the declaration is repeated each time the function is called
00042 2408 01035 ADDWF 08,W//
00044 6E01 01036 MOVWF 01
// again
00062 5009 01037 MOVF 09,W
00064 2408 01038 ADDWF 08,W
00066 6E01 01039 MOVWF 01
//and agin
00080 5009 01040 MOVF 09,W
00082 2408 01041 ADDWF 08,W
00084 6E01 01042 MOVWF 01
01043 .................... }
01044 ....................
01045 .................... void main(void){
00004 6AF8 01046 CLRF FF8
00006 9ED0 01047 BCF FD0.7
00008 50C1 01048 MOVF FC1,W
0000A 0BF0 01049 ANDLW F0
0000C 6EC1 01050 MOVWF FC1
0000E 0E00 01051 MOVLW 00
00010 010F 01052 MOVLB F
00012 6F38 01053 MOVWF x38
00014 6F3C 01054 MOVWF x3C
00016 6F39 01055 MOVWF x39
00018 6F3A 01056 MOVWF x3A
0001A 6F3B 01057 MOVWF x3B
0001C 0101 01058 MOVLB 1
0001E 6B88 01059 CLRF x88
00020 6A77 01060 CLRF F77
00022 6A78 01061 CLRF F78
00024 6A79 01062 CLRF F79
00026 6A05 01063 CLRF 05
01064 .................... int c =0;
01065 .................... for (int i=0;i<4;i++)
00028 6A06 01066 CLRF 06
0002A 5006 01067 MOVF 06,W
0002C 0803 01068 SUBLW 03
0002E E311 01069 BNC 0052
01070 .................... for (int k=0;k < 3;k++)
00030 6A07 01071 CLRF 07
00032 5007 01072 MOVF 07,W
00034 0802 01073 SUBLW 02
00036 E30B 01074 BNC 004E
01075 .................... c = suma(i,k);
00038 C006 F008 01076 MOVFF 06,08
0003C C007 F009 01077 MOVFF 07,09
00046 C001 F005 01078 MOVFF 01,05
0004A 2A07 01079 INCF 07,F
0004C D7F2 01080 BRA 0032
0004E 2A06 01081 INCF 06,F
00050 D7EC 01082 BRA 002A
01083 .................... for (i=0;i<10;i++)
00052 6A06 01084 CLRF 06
00054 5006 01085 MOVF 06,W
00056 0809 01086 SUBLW 09
00058 E30B 01087 BNC 0070
01088 .................... c = suma(i,i);
0005A C006 F008 01089 MOVFF 06,08
0005E C006 F009 01090 MOVFF 06,09
00068 C001 F005 01091 MOVFF 01,05
0006C 2A06 01092 INCF 06,F
0006E D7F2 01093 BRA 0054
01094 .................... for (i=0;i<10;i++)
00070 6A06 01095 CLRF 06
00072 5006 01096 MOVF 06,W
00074 0809 01097 SUBLW 09
00076 E30B 01098 BNC 008E
01099 .................... c = suma(i,i);
00078 C006 F008 01100 MOVFF 06,08
0007C C006 F009 01101 MOVFF 06,09
00086 C001 F005 01102 MOVFF 01,05
0008A 2A06 01103 INCF 06,F
0008C D7F2 01104 BRA 0072
01105 ....................
01106 ....................
01107 ....................
01108 ....................
01109 .................... }
0008E 0003 1110 SLEEP
Configuration Fuses:
Word 1: E200 HSH NOPLLEN PRIMARY_ON FCMEN IESO
Word 2: 1C1E PUT BROWNOUT BORV19 NOWDT WDT128
Word 3: BF00 CCP2C1 PBADEN CCP3B5 HFOFST TIMER3C0 CCP2D2 MCLR
Word 4: 0081 STVREN NOLVP NOXINST NODEBUG
Word 5: C00F NOPROTECT NOCPB NOCPD
Word 6: E00F NOWRT NOWRTC NOWRTB NOWRTD
Word 7: 400F NOEBTR NOEBTRB
SYMBOL TABLE
LABEL VALUE
_RETURN_ 00000001
MAIN.c 00000005
MAIN.i 00000006
MAIN.k 00000007
suma.a 00000008
suma.b 00000009
CCP_5_LOW 00000F55
CCP_5 00000F55
CCP_5_HIGH 00000F56
CCP_4 00000F58
CCP_4_LOW 00000F58
CCP_4_HIGH 00000F59
CCP_3 00000F5E
CCP_3_LOW 00000F5E
CCP_3_HIGH 00000F5F
CCP_2_LOW 00000F67
CCP_2 00000F67
CCP_2_HIGH 00000F68
C2OUT 00000F78
C1OUT 00000F79
CCP_1 00000FBE
CCP_1_LOW 00000FBE
CCP_1_HIGH 00000FBF
Allocation: 0000EEEF
MAIN 00000000
suma 00000000
MEMORY USAGE |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19559
|
|
Posted: Tue Jan 26, 2021 2:57 am |
|
|
You are missing the point.
Declaring a function as 'inline', _specifically_ MAKES the compiler
generate the code for every place it is used.
It is _you_ who are making the compiler generate the code for every
place it is used.
Simply declare the function without #inline, and the code will be
generated just once, and called each time it is used.
BUT, this is inherently slower than having the code regenerated for
each location. Done like this, there is no call/return, so a couple of
double cycle instructions quicker.
It is not the compiler doing this. You are specifically telling the compiler
to make the code 'inline'. As PCM says this is normally done for speed. |
|
|
Felo
Joined: 23 May 2020 Posts: 7
|
Forgive the insistence. |
Posted: Tue Jan 26, 2021 4:07 am |
|
|
Hello:
I understand that generating the code of the function in the place it is called increases the execution speed as you well explained. The inline function is used for this purpose.
I can't understand how generating the code in the declaration that never executes (the one that appears in the declaration of the inline function) can help.
Thanks for your time. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19559
|
|
Posted: Tue Jan 26, 2021 4:33 am |
|
|
Er. It doesn't.
The assembler .lst file is not (and never is), 'in code order'. It is blocks of code
placed in the order they are typed.
So it has the #inline function shown where it is declared. However the order
'in use', is determined by the address the function is actually placed at.
So the routines for the #use RS232 are shown just below this in the listing.
Same for delay code, etc. etc.. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9250 Location: Greensville,Ontario
|
|
Posted: Tue Jan 26, 2021 6:19 am |
|
|
In the early days ( V2.534...) I was confused about the listing, then saw that the addresses 'all over the place'. So I used 'sort.exe' ( A DOS program) , to 'reorder' the listing based upon the address where code is stored. That allowed me to easily SEE and understand what was going on.
At the time I was doing a 'time sensitive' program(bit banged serial) and needed to KNOW exactly how the PIC was being coded. |
|
|
Felo
Joined: 23 May 2020 Posts: 7
|
Please observe the generated .hex file that I attach |
Posted: Tue Jan 26, 2021 7:06 am |
|
|
You are correct that the order that appears in the list corresponds to the order in which the instructions were written and not to the order in which the code is generated.
I attach the .hex file that was generated for the .lst file that we are analyzing.
File Summary:
Filename: inlineTest.hex
File Status: Good
Target Chip: PIC18F46K22
File Type: INHX32 (Intel Hex)
Program Size: 72 Instructions (1%)
Program Range: 0000-008F
Data EE Size: 0 bytes
Checksum: A5C1
Config Size: 14 bytes
Created: 26-Jan-21 02:48
Addresses are: Byte addresses
Program Memory
000000: EF02 F000 6AF8 9ED0 50C1 0BF0 6EC1 0E00
000010: 010F 6F38 6F3C 6F39 6F3A 6F3B 0101 6B88
000020: 6A77 6A78 6A79 6A05 6A06 5006 0803 E311
000030: 6A07 5007 0802 E30B C006 F008 C007 F009
000040: 5009 2408 6E01 C001 F005 2A07 D7F2 2A06
000050: D7EC 6A06 5006 0809 E30B C006 F008 C006
000060: F009 5009 2408 6E01 C001 F005 2A06 D7F2
000070: 6A06 5006 0809 E30B C006 F008 C006 F009
000080: 5009 2408 6E01 C001 F005 2A06 D7F2 0003
Configuration Words
300000: E200 1C1E BF00 0081 C00F E00F 400F
;PIC18F46K22
;CRC=9164 CREATED="26-Jan-21 02:48"
Please note that in the directions
Addresses Content
00040 to 44 has 5009 2408 6E01
00062 to 66 has 5009 2408 6E01
Like 0080 to 0084
Content that corresponds to what appears in the .lst file
01032 .................... int suma(int a, int b) {
01033 .................... return (a +b);
00040 5009 01034 MOVF 09,W
00042 2408 01035 ADDWF 08,W
00044 6E01 01036 MOVWF 01
00062 5009 01037 MOVF 09,W
00064 2408 01038 ADDWF 08,W
00066 6E01 01039 MOVWF 01
00080 5009 01040 MOVF 09,W
00082 2408 01041 ADDWF 08,W
00084 6E01 01042 MOVWF 01
Those instructions are in the program memory but never executed. That's what I mean.
I consider the PICC a magnificent tool, so I try to understand it, and perfect it.
Thank you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19559
|
|
Posted: Tue Jan 26, 2021 7:15 am |
|
|
Of course they are executed. Where do you think the processor goes after
the instruction at 0x3C?.
Look at the order I posted the code. |
|
|
Felo
Joined: 23 May 2020 Posts: 7
|
Thank you for your patience. |
Posted: Tue Jan 26, 2021 7:48 am |
|
|
Now I realize.
Ttelmah wrote: | Of course they are executed. Where do you think the processor goes after
the instruction at 0x3C?.
Look at the order I posted the code. |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
|
|
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
|