4
\$\begingroup\$

I'd like to know how many lines of C code in average corresponds to 1Ko programmable memory for PIC18F microcontrollers

Or how many lines of assembly instructions ?

asked Apr 25, 2015 at 13:54
\$\endgroup\$
7
  • 4
    \$\begingroup\$ None. I filled it with data instead. \$\endgroup\$ Commented Apr 25, 2015 at 14:28
  • 4
    \$\begingroup\$ There is nothing opinion based about the answer to this question. It is an easy factual statement. \$\endgroup\$ Commented Apr 25, 2015 at 16:52
  • 3
    \$\begingroup\$ I'm with @Passerby, there is no opinion involved! It may be argued that the questioner is clueless about the translation process from an high level language like C to machine language, but the potential answers are not a matter of opinion at all! If I could, I would vote to reopen. \$\endgroup\$ Commented Apr 25, 2015 at 17:32
  • 1
    \$\begingroup\$ @LorenzoDonati This depends a lot on the qualities of the C code. On a PIC, a function call takes more instructions than ++i; It's anyone's guess as to what code to use as a benchmark for this question. \$\endgroup\$ Commented May 1, 2015 at 3:44
  • 2
    \$\begingroup\$ @NickAlexeev Yes, I agree, but it could have been made in a good answer, nonetheless (IMO). This is one of those cases where one could have spent a couple dozen of lines to explain the fact: a non-definitive answer (in this case) could be an answer, since it could point out why you cannot in general estimate the memory footprint of machine code generated by a C compiler without further information on the compiler, compiler options, actual C code, etc. I think it could be a useful reference and it doesn't fall in the "too broad" category. \$\endgroup\$ Commented May 1, 2015 at 10:54

2 Answers 2

11
\$\begingroup\$

Let's take some real world examples. I wrote a simple C program, which I think represents typical C code. Some could argue one way or another that it doesn't, but I think it will make my point.

Here is the C code:

unsigned short m [20];
int main()
{
 unsigned char a, x, i;
 unsigned short b, y;
 unsigned long c, z;
 a = b = c = 0;
 for (i=0; i < 20; i++)
 {
 a++;
 b++;
 c++;
 x = a * 3;
 y = b * 3;
 z = c * 3;
 if (a > 50)
 {
 a = 0;
 }
 m[i] = a / (b / (c - z) * x) + i;
 }
}

In addition to the 8-bit PIC18F asked about by the OP, I also compiled it for three other processors: an 8-bit 8051, an 8-bit PIC16F, and a 32-bit PIC32, and for each I took a look at the disassembly code to get the number of instructions and the number of bytes for each line of C code. Due to the length, I decided not to post the disassembly code here.

For the C code above, the PIC18F used 168 instructions and 336 bytes of code (all machine instructions were two bytes long). That however doesn't include some helper routines since the PIC18F for example doesn't have a hardware divide instruction, so a subroutine call is made for that. Of course these helper routines are shared for all the code in a program. So I'll ignore them since they probably affect the code size in a real program by a few percent.

The PIC16F used 272 instructions and 476 bytes of code (all machine instructions on the PIC16F are 14-bits long, so I converted this to bytes). Like the PIC18F, the PIC16F doesn't have a hardware divide instruction, so it also uses helper routines which were not included in the count.

The 8051 used 99 instructions and 175 bytes of code, or an average of 1.77 bytes per machine instruction. Like the PIC18F, the 8051 doesn't have a hardware divide instruction, so it also uses helper routines which were not included in the count.

The PIC32 used 68 instructions and 272 bytes of code. All machine instructions on the PIC32 take 4 bytes, unlike for example the 8051 where instructions can be variable length: 1, 2 or 3 bytes.

There are 11 lines of executable code in my C program. So that works out to be 15.2 instructions per line of C for the for the PIC18F; 24.7 instructions for the PIC16F; 9 instructions for the 8051; and 6.2 instructions For the PIC32.

As far as program bytes per line of code, the numbers are 30.5 bytes for the PIC18F; 43.3 bytes for the PIC16F; 15.9 bytes for the 8051; and 24.7 bytes for the PIC32. So the 8051 wins in terms of least number of bytes per line of C code.

However, for the three PIC compilers, I was not using the optimized versions (they have three versions of each compiler: free, standard, and pro). I was using the free one. Microchip claims the pro compilers can reduce code space by 60%. In my own work experience with the PIC32 pro compiler, I was getting 40-50% reduction. So I'm going to use 50% here as a compromise.

So the numbers become:

 Instructions/line of code Bytes/line of code
PIC18F 7.6 (est) 15.2 (est) 
PIC16F 12.4 (est) 21.6 (est)
8051 9 15.9
PIC32 3.1 (est) 12.3 (est)

Interesting that the number of bytes per line of code is so similar between three of the processors, and not that much higher for the PIC16F.

So to answer the original question, for the PIC18F you get 1024/168 * 11 = 67.0 lines of C per 1K of code; for the PIC16F you can get 1024/272 * 11 = 41.4 lines of C, for the 8051 you can get 1024/175 * 11 = 64.4 lines of C, and for the PIC32, 1024/136 * 11 = 82.8 lines of C. So you get the most number of lines of C using the PIC32. I think the average number of lines of C (which is what the OP asked for) for most programs is probably somewhere between 25 and 120 lines of code depending on the processor and the program.

As far as lines of assembly instructions, for the PIC18F you can get 7.6 * 67.0 = 509 instructions; for the PIC16F you can get 12.3 * 40.4 * 16/14 = 567.9 instructions, for the 8051 you can get 9 * 62.8 = 565.2 instructions, and for the PIC32, 3.1 * 82.8 = 256.7

 Lines of C in 1K bytes Instructions in 1K bytes
PIC18F 65.5 (est) 497.8 (est) 
PIC18F 40.4 (est) 567.9 (est)
8051 62.8 565.2
PIC32 80.9 (est) 256.7 (est)

Note the "Instructions in 1K bytes" actually is just over 500 for the PIC18F, and 250 for the PIC32, since they use 2 and 4 bytes instruction respectively. The number for the PIC16F is higher due to the allowance for its 14-bit words.

answered May 2, 2015 at 3:57
\$\endgroup\$
4
  • \$\begingroup\$ What about optimization? Did you compile both with out it? \$\endgroup\$ Commented May 2, 2015 at 7:26
  • \$\begingroup\$ @Passerby I don't have the optimizing versions of these compilers at home, only at work (if I remember correctly, the optimized PIC32 compiler is around 800ドル). From my experience there, the optimized code was about 40% smaller than the unoptimized. I'll include that in my answer. Thanks. \$\endgroup\$ Commented May 2, 2015 at 8:01
  • \$\begingroup\$ "exactly 500". Not quite, since 1KB of memory on a uC is 1024B (they use the 2^10 system, not the 10^3 one). \$\endgroup\$ Commented May 2, 2015 at 15:04
  • \$\begingroup\$ @TomCarpenter I'll redo my calculations using 1024 instead of 1000. Thanks. \$\endgroup\$ Commented May 2, 2015 at 16:46
8
\$\begingroup\$

As for C - it can be one line, or it can be a thousand. Depending on the constructs and optimization. For assembly it is clear - PIC18 has an instruction set composed of 16 and 32bit long instructions. So 1Kb can contain at 1024/2=512 instructions at most.

answered Apr 25, 2015 at 14:01
\$\endgroup\$
6
  • \$\begingroup\$ The OP didn't ask how many machine instructions in 1K of code, he asked for how many lines of C code. \$\endgroup\$ Commented May 2, 2015 at 2:12
  • \$\begingroup\$ @tcrosley If you look carefully at the question you will notice the line about assembly that mostly translating one line to one instruction. So the answer is addressing both parts of the question. \$\endgroup\$ Commented May 2, 2015 at 2:16
  • 1
    \$\begingroup\$ Well, I disagree that on most processors, on average one line of C translates to one machine instruction. \$\endgroup\$ Commented May 2, 2015 at 2:19
  • 4
    \$\begingroup\$ @tcrosley Do you mind re-reading the question and the answer? The answer is stating that you can't tell for C. But you can for assembly. \$\endgroup\$ Commented May 2, 2015 at 2:21
  • \$\begingroup\$ one line of c code can have several constants and several variable assiggments, there'n no way that's going to reduce to one istruction. \$\endgroup\$ Commented May 3, 2015 at 11:06

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.