Hello ! I have a problem which I can't resolve. I wrote program for 89C2051 for one of my friend in Basom Basic compiler (http://www.mcselec.com). Compiled code was about 1945 bytes. Since I prefer C, I transalte Bascom basic to C. But when I compile, generated code was 2313. I try to change optimization parameters, but generated code never go below 2313. Even bigger. Where am I wrong ? Is it possible that stupid Basic make smaller code tne best C compiler ? Then I find out that this code: while (1) { printf ("Hello World\n"); } generate fully 1093 bytes (!) for Atmel 89C2051. 1093 bytes???? Three lines? Same program in Bascom generate only 154 (!) bytes. When I remove all "printf" from my C code, generated code was arond 2200 byte. But, with same action in Basic code (remove all "print") 1340 bytes long code. Exactly same program in Keil C and Bascom basic generate 860 byte smaller code ! I don't belive this. Do I have to program in (stupid) Basic if I want smaller code ? I still belive I did mistake somewhere, so I need help. I will send both C and basic code for interested people. With best regards !
Mladen, If I were in your position I would take Graham Cole up on his kind offer to send you his function user_printf(). It may be a good fit for your application as is or you might be able to strip it down even more.
"NO communication to "the real world" need be that complicated, if it is the maybe some post-processing at the receiving end would be an idea." Post processing requires software. Formatted ASCII data can be viewed or logged to disk by any terminal emulation program. That saves work. "No, I am not; however I do belong to the "the '51 is not a PC club"" So the fact that the 8051 is not a PC means that if you do use a (relatively) high level language such as 'C' you must avoid using some of the most powerful library functions - why? Because it somehow isn't proper? Stefan
To mr. Graham Cole ! Please send me your custom print() function. And some explanation how to install it and use. With regards ! Mladen Bruck
I will need your e-mail address.
Ops ;) mladen.bruck@pincom.net
So the fact that the 8051 is not a PC means that if you do use a (relatively) high level language such as 'C' relatively high? what about efficient. Because it somehow isn't proper? The next we will see is "just add a megabyte of ROM and you can do the proper thing and use C++" Erik
"relatively high? what about efficient" 'C' is relatively efficient. What's your point? "The next we will see is "just add a megabyte of ROM and you can do the proper thing and use C++"" You already can use C++ without adding a megabyte of ROM. Perhaps you should try it? Stefan
Stefan, Nothing personal, but you come across as a "if it is too slow buy a faster (more expensive) processor, do not try to streamline the code, it may make it not proper" person. We are discussing the difference between a microcontroller and a microprocessor related to purpose, use, functionality and application. I have worked with "real C" programmers and they professed that there was no need whatsoever to understand the purpose of the equipment such as no C++ for low cost or ultrafast response. I once revised a development where a bloated RTOS with some "real C" code bugged the processor so far down that the "real C programmer" suggested a change to an ARM processor. It took about a month to get the bloatings out of the code (still using C) and then the '51 was more than sufficient. Re C++ you need to read this interview http://www.ganssle.com/tem/tem17.pdf Trevlig kvaell Erik
You can write bloated code in any language, including assembly. You can write "efficient" code in C, and yes, even in C++ -- if you know what you're doing. C++ in particular is more subtle and thus more difficult than it seems on casual inspection. The smallest overall program is not necessarily one where individual basic blocks are the smallest.
You can write bloated code in any language, including assembly. I agree; however it is a characteristic of "real programmers" as opposed to "embedded programmers" to concentrate on the elegance (in their opinion) and state of the art of the code rather than the efficiency. I consulted for a while with a major cellphone company and the "real programmers" decided to go to C++. This led to the need to double the clockspeed of the processor. Before this happened I said, wrote and almost screamed "faster clock is more battery usage and one of the problems we have is is battery charge life". They went ahead anyhow "because it is the right thing to do" and now the lack of battery life has led to a sharp decline in sales for that company. Erik
The method how to handle non-constant format strings is obvious, isn't it? Apparently, not obvious enough. The mechanism that you outline is suitable for an interpreted language, but a compiled application has to be self-sufficient. The app can not, at run time, upon encountering a foreign format specifier, ask the compiler for anything. - Dave
Dave, I can't see anything wrong with Hans's description. What he describes happens at compile time. His third point was that if the compiler sees a non-constant string anywhere in the code, then it gives up trying to optimise, and uses the full-featured version of printf().
You can get into situations where, for example, if there are multiple source files, each source module calls for a different "edition" of printf. If this is the case, it is actually up to the linker to resolve which printf gets included. It's fairly easy for the compiler to say, "Oh, this module calls printf and only has an unsigned int in the format string. OK, include printf#1." In another module, however, the compiler might say, "Oh. this module calls printf and uses floating-point format specifiers in the format string (but no unsigned ints are used). OK, include printf#4." Now, the linker has to make sense of all of these different printf functions. And, at the end of the day, the linker includes most of what's in the standard printf. The only applications this would work well for would be the Hello World example. I mean, if I include sprintf in my application, I'm going to use it to my best advantage. I'm not going to try to use a printf SUBSET to save memory. If memory is that precious, I'm going to write my own formatting routines. printf has been an acknowledged memory hog since C was invented. There have been very few successful attempts at reducing its size. For its size, I think it does quiet well. Jon
I just downloaded the BASCOM demo and played around for a while. It's pretty neat. After playing around for a while, I decided to run a real program and compare it to C51. Not wanting to spend the rest of my life on this, I chose the SIEVE. Here are the results: BASCOM: Code Size: 866 Bytes Execution Speed: 23.553726 Seconds Keil (using printf): Code Size: 1,248 Bytes Execution Speed: 6.331546 Seconds Keil (using putchar and puts): Code Size: 524 Bytes Execution Speed: 6.330123 Seconds I did all speed testing with the uVision2 Debugger/Simulator under identical circumstances. From this little comparison, I think you can tell that the printf is what kills the C code--but not the performance. And, the difference between a CUSTOM formatter (using puts and putchar) and printf saves 724 bytes. I'll be more than happy to post the source for these things (of course, the SIEVE source comes with the Keil tools) if anyone wants to check my work. Jon
And...with linker code packing... Keil (using putchar and puts and linker code packing): Code Size: 486 Bytes Execution Speed: 6.330105 Seconds Jon