Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Getting the size of a C function

Reply
Thread Tools

Getting the size of a C function

 
 
bartc
Guest
Posts: n/a
 
      01-23-2010

"Mark Borgerson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)-september.org...
> In article <(E-Mail Removed)>,
> http://www.velocityreviews.com/forums/(E-Mail Removed) says...
>> On Fri, 22 Jan 2010 22:53:18 +0000, john wrote:
>>
>> > I need to know the size of a function or module because I need to
>> > temporarily relocate the function or module from flash into sram to
>> > do firmware updates.

>>
>> Do you need to be able to run it from RAM? If so, simply memcpy()ing it
>> may not work. And you would also need to copy anything which the function
>> calls (just because there aren't any explicit function calls in the
>> source
>> code, that doesn't mean that there aren't any in the resulting object
>> code).
>>
>>

> At the expense of a few words of code and a parameter, you could do
>
>
> int MoveMe(...., bool findend){
> if(!findend){
>
> // do all the stuff the function is supposed to do
>
> } else Markend();
>
> }
>


If you're going to add a special parameter (and assume the return type is
compatible with a return address), it might be possible to use gcc's feature
of obtaining the address of a label.

Then findend can return the address of a label placed near the closing brace
of the function (which possibly may be less likely to be rearranged than a
function call).

int MoveMe(...., bool findend){
if(findend) return (int)&&endoffunction;

// do all the stuff the function is supposed to do

endoffunction:
return 0;
}

--
Bartc

 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      01-23-2010
Mark Borgerson <(E-Mail Removed)> writes:

> In article <(E-Mail Removed)>, (E-Mail Removed)
> says...
>> Mark Borgerson <(E-Mail Removed)> writes:
>> You seem to be assuming that the compiler emits machine code that
>> is in the same order as the corresponding C code, i.e. that the
>> call to Markend() will occur at the end of MoveMe(). This is not
>> a good assumption.

>
> This would certainly be a dangerous technique on a processor
> with multi-threading and possible out-of-order execution.
> I think it will work OK on the MSP430 that is the CPU where
> I am working on a flash-burning routine.


Threading and out-of-order execution has little if anything to do
with it. The issue is the order of the code emitted by compiler,
not the order of the code's execution.
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
 
 
 
Mark Borgerson
Guest
Posts: n/a
 
      01-23-2010
In article <(E-Mail Removed)>, (E-Mail Removed)
says...
> Mark Borgerson <(E-Mail Removed)> writes:
>
> > In article <(E-Mail Removed)>, (E-Mail Removed)
> > says...
> >> Mark Borgerson <(E-Mail Removed)> writes:
> >> You seem to be assuming that the compiler emits machine code that
> >> is in the same order as the corresponding C code, i.e. that the
> >> call to Markend() will occur at the end of MoveMe(). This is not
> >> a good assumption.

> >
> > This would certainly be a dangerous technique on a processor
> > with multi-threading and possible out-of-order execution.
> > I think it will work OK on the MSP430 that is the CPU where
> > I am working on a flash-burning routine.

>
> Threading and out-of-order execution has little if anything to do
> with it. The issue is the order of the code emitted by compiler,
> not the order of the code's execution.
>

But woudn't an optimizing compiler generating code for a
complex processor be more likely to compile optimize in
a way that changed the order of operations? I think
that might apply particularly to a call to a function
that returns no result to be used in a specific
place inside the outer function.


Mark Borgerson

 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      01-23-2010
Mark Borgerson wrote:
) In article <(E-Mail Removed)>, (E-Mail Removed)
) says...
)> Mark Borgerson <(E-Mail Removed)> writes:
)>
)> > In article <(E-Mail Removed)>, (E-Mail Removed)
)> > says...
)> >> Mark Borgerson <(E-Mail Removed)> writes:
)> >> You seem to be assuming that the compiler emits machine code that
)> >> is in the same order as the corresponding C code, i.e. that the
)> >> call to Markend() will occur at the end of MoveMe(). This is not
)> >> a good assumption.
)> >
)> > This would certainly be a dangerous technique on a processor
)> > with multi-threading and possible out-of-order execution.
)> > I think it will work OK on the MSP430 that is the CPU where
)> > I am working on a flash-burning routine.
)>
)> Threading and out-of-order execution has little if anything to do
)> with it. The issue is the order of the code emitted by compiler,
)> not the order of the code's execution.
)>
) But woudn't an optimizing compiler generating code for a
) complex processor be more likely to compile optimize in
) a way that changed the order of operations? I think
) that might apply particularly to a call to a function
) that returns no result to be used in a specific
) place inside the outer function.

More specifically, it could generate code like this:
(example in pseudocode)

(begin MoveMe)
TEST var
SKIP NEXT on zero
JUMP Markend
.... ; the rest of the code
RETURN
(end MoveMe)


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
Jon Kirwan
Guest
Posts: n/a
 
      01-23-2010
On Sat, 23 Jan 2010 13:17:45 -0800, Mark Borgerson wrote:

>In article <(E-Mail Removed)>, (E-Mail Removed)
>says...
>> Mark Borgerson <(E-Mail Removed)> writes:
>>
>> > In article <(E-Mail Removed)>, (E-Mail Removed)
>> > says...
>> >> Mark Borgerson <(E-Mail Removed)> writes:
>> >> You seem to be assuming that the compiler emits machine code that
>> >> is in the same order as the corresponding C code, i.e. that the
>> >> call to Markend() will occur at the end of MoveMe(). This is not
>> >> a good assumption.
>> >
>> > This would certainly be a dangerous technique on a processor
>> > with multi-threading and possible out-of-order execution.
>> > I think it will work OK on the MSP430 that is the CPU where
>> > I am working on a flash-burning routine.

>>
>> Threading and out-of-order execution has little if anything to do
>> with it. The issue is the order of the code emitted by compiler,
>> not the order of the code's execution.
>>

>But woudn't an optimizing compiler generating code for a
>complex processor be more likely to compile optimize in
>a way that changed the order of operations? I think
>that might apply particularly to a call to a function
>that returns no result to be used in a specific
>place inside the outer function.


Ben quite correctly brought you up short on the right point.
Your example was, just to refresh ourselves:

>: int MoveMe ( ...., bool findend ) {
>: if ( !findend ) {
>: // do normal function stuff
>: } else
>: Markend();
>: }


Let's divert from this for a moment and take the case of a
for-loop in c. It looks like:

>: for ( init-block; condition; iterate-block )
>: body-block;


A compiler will often translate this into this form:

>: init-block;
>: goto A;
>: B: body-block;
>: C: iterate-block;
>: A: if ( condition ) goto B;
>: D:


(The reason for the C label is to support the continue-
statement and the reason for the D label is to support a
break-statement, of course.)

The straight interpretation would have been more like this:

>: init-block;
>: A: if ( !condition ) goto D;
>: B: body-block;
>: C: iterate-block;
>: goto A;
>: D:


But note that the execution of the for-loop's main body,
presumed by the compiler to have "many iterations" as a
reasonable guess, includes execution for the "goto A"
statement in each and every iteration. But so is, in effect,
the conditional test, too. In other words, it takes longer
to execute the body, even if that only means the execution of
one jump instruction. It's more efficient to redesign the
model used by the compiler to the first example I gave,
merely because the c compiler takes the position that the
added one-time execution of the first "goto A" will be the
lower cost approach (which it almost always will be.)

Now let's assume that the compiler takes the position that
the first case of an if-statement section is the more
frequently travelled one. In other words, when the
conditional case is executed, it will more often be "true"
than "false." The model used might very well then be to
convert:

>: if ( condition )
>: s1-block;
>: else
>: s2-block;


into:

>: if ( !condition ) goto A;
>: s2-block;
>: goto B;
>: A: s1-block;
>: B:


This provides s1-block execution with one less jump and
therefore lets it execute slightly faster with the idea that
it is the preferred path.

So let's revisit your example again in this light:

>: int MoveMe ( ...., bool findend ) {
>: if ( !findend ) {
>: // do normal function stuff
>: } else
>: Markend();
>: }


This _may_ be taken by a c compiler to be:

>: int MoveMe ( ...., bool findend ) {
>: if ( findend ) goto A;
>: Markend();
>: goto B;
>: A: // do normal function stuff
>: B:
>: }


Leaving your function call to Markend not exactly where you'd
have liked to see it occur.

An old book you can pick up talking about a method used to
_explicitly_ inform the compiler about statistics of branch
likelihoods is the Ph.D. thesis by John Ellis:

http://mitpress.mit.edu/catalog/item...d=5098&ttype=2

Worth a read, some snowy day.

Jon
 
Reply With Quote
 
Mark Borgerson
Guest
Posts: n/a
 
      01-23-2010
In article <(E-Mail Removed)>, (E-Mail Removed)
says...
> Mark Borgerson wrote:
> ) In article <(E-Mail Removed)>, (E-Mail Removed)
> ) says...
> )> Mark Borgerson <(E-Mail Removed)> writes:
> )>
> )> > In article <(E-Mail Removed)>, (E-Mail Removed)
> )> > says...
> )> >> Mark Borgerson <(E-Mail Removed)> writes:
> )> >> You seem to be assuming that the compiler emits machine code that
> )> >> is in the same order as the corresponding C code, i.e. that the
> )> >> call to Markend() will occur at the end of MoveMe(). This is not
> )> >> a good assumption.
> )> >
> )> > This would certainly be a dangerous technique on a processor
> )> > with multi-threading and possible out-of-order execution.
> )> > I think it will work OK on the MSP430 that is the CPU where
> )> > I am working on a flash-burning routine.
> )>
> )> Threading and out-of-order execution has little if anything to do
> )> with it. The issue is the order of the code emitted by compiler,
> )> not the order of the code's execution.
> )>
> ) But woudn't an optimizing compiler generating code for a
> ) complex processor be more likely to compile optimize in
> ) a way that changed the order of operations? I think
> ) that might apply particularly to a call to a function
> ) that returns no result to be used in a specific
> ) place inside the outer function.
>
> More specifically, it could generate code like this:
> (example in pseudocode)
>
> (begin MoveMe)
> TEST var
> SKIP NEXT on zero
> JUMP Markend
> ... ; the rest of the code
> RETURN
> (end MoveMe)
>


I've actually seen constructs like that intentionally
coded in assembly language, since it saves the
address push and pop you would need need in a branch
to a subroutine. I haven't seen it recently
in compiler output, but that may be because I
limit optimization to make debugging easier. Since
I do limited numbers of systems in a niche market,
I save money by spending a few extra dollars on
more memory and CPU cycles if it saves me a few
hours of debugging time.


In any of these instances, I would certainly review
the assembly code to make sure the compiler was doing
what I intended in the order I wanted. Maybe programmers
in comp.lang.c don't do that as often as programmers
in comp.arch.embedded.




Mark Borgerson

 
Reply With Quote
 
Mark Borgerson
Guest
Posts: n/a
 
      01-23-2010
In article <(E-Mail Removed)>,
(E-Mail Removed) says...
> On Sat, 23 Jan 2010 13:17:45 -0800, Mark Borgerson wrote:
>
> >In article <(E-Mail Removed)>, (E-Mail Removed)
> >says...
> >> Mark Borgerson <(E-Mail Removed)> writes:
> >>
> >> > In article <(E-Mail Removed)>, (E-Mail Removed)
> >> > says...
> >> >> Mark Borgerson <(E-Mail Removed)> writes:
> >> >> You seem to be assuming that the compiler emits machine code that
> >> >> is in the same order as the corresponding C code, i.e. that the
> >> >> call to Markend() will occur at the end of MoveMe(). This is not
> >> >> a good assumption.
> >> >
> >> > This would certainly be a dangerous technique on a processor
> >> > with multi-threading and possible out-of-order execution.
> >> > I think it will work OK on the MSP430 that is the CPU where
> >> > I am working on a flash-burning routine.
> >>
> >> Threading and out-of-order execution has little if anything to do
> >> with it. The issue is the order of the code emitted by compiler,
> >> not the order of the code's execution.
> >>

> >But woudn't an optimizing compiler generating code for a
> >complex processor be more likely to compile optimize in
> >a way that changed the order of operations? I think
> >that might apply particularly to a call to a function
> >that returns no result to be used in a specific
> >place inside the outer function.

>
> Ben quite correctly brought you up short on the right point.
> Your example was, just to refresh ourselves:
>
> >: int MoveMe ( ...., bool findend ) {
> >: if ( !findend ) {
> >: // do normal function stuff
> >: } else
> >: Markend();
> >: }

>
> Let's divert from this for a moment and take the case of a
> for-loop in c. It looks like:
>
> >: for ( init-block; condition; iterate-block )
> >: body-block;

>
> A compiler will often translate this into this form:
>
> >: init-block;
> >: goto A;
> >: B: body-block;
> >: C: iterate-block;
> >: A: if ( condition ) goto B;
> >: D:

>
> (The reason for the C label is to support the continue-
> statement and the reason for the D label is to support a
> break-statement, of course.)
>
> The straight interpretation would have been more like this:
>
> >: init-block;
> >: A: if ( !condition ) goto D;
> >: B: body-block;
> >: C: iterate-block;
> >: goto A;
> >: D:

>
> But note that the execution of the for-loop's main body,
> presumed by the compiler to have "many iterations" as a
> reasonable guess, includes execution for the "goto A"
> statement in each and every iteration. But so is, in effect,
> the conditional test, too. In other words, it takes longer
> to execute the body, even if that only means the execution of
> one jump instruction. It's more efficient to redesign the
> model used by the compiler to the first example I gave,
> merely because the c compiler takes the position that the
> added one-time execution of the first "goto A" will be the
> lower cost approach (which it almost always will be.)


I've also run across main processing loops such as

void MainLoop(void)
while(1){
get user input
execute commands
}
MarkEnd();
}

where MarkEnd doesn't appear in the generated machine
code, because the compiler, even at lowest optimization
setting, recognizes that the code after the loop
will never get executed.


>
> Now let's assume that the compiler takes the position that
> the first case of an if-statement section is the more
> frequently travelled one. In other words, when the
> conditional case is executed, it will more often be "true"
> than "false." The model used might very well then be to
> convert:
>
> >: if ( condition )
> >: s1-block;
> >: else
> >: s2-block;

>
> into:
>
> >: if ( !condition ) goto A;
> >: s2-block;
> >: goto B;
> >: A: s1-block;
> >: B:

>
> This provides s1-block execution with one less jump and
> therefore lets it execute slightly faster with the idea that
> it is the preferred path.
>
> So let's revisit your example again in this light:
>
> >: int MoveMe ( ...., bool findend ) {
> >: if ( !findend ) {
> >: // do normal function stuff
> >: } else
> >: Markend();
> >: }

>
> This _may_ be taken by a c compiler to be:
>
> >: int MoveMe ( ...., bool findend ) {
> >: if ( findend ) goto A;
> >: Markend();
> >: goto B;
> >: A: // do normal function stuff
> >: B:
> >: }

>
> Leaving your function call to Markend not exactly where you'd
> have liked to see it occur.


That could certainly occur. I would be interested in the logic
that could come to the conclusion that one or the other
of the branches would be more likely to occur. I guess the
compiler could check all the calls to MoveMe and compare the
number of times the findend parameter was true and false. However that
might be pretty difficult if a variable was used.

Still, a good reason, as I've said in other posts, to look
at the resulting assembly langauage. I did it for one
MSP430 compiler, and it worked the way I wanted. YMMV.

I wonder how many compilers would make that kind of optimization
and under which optimization settings.
>
> An old book you can pick up talking about a method used to
> _explicitly_ inform the compiler about statistics of branch
> likelihoods is the Ph.D. thesis by John Ellis:
>
> http://mitpress.mit.edu/catalog/item...d=5098&ttype=2
>
> Worth a read, some snowy day.


Those are pretty rare in Corvallis. Only one or two so far this winter.
Now, rainy days----those I get in plentitude!
>

Mark Borgerson


 
Reply With Quote
 
Jon Kirwan
Guest
Posts: n/a
 
      01-24-2010
On Sat, 23 Jan 2010 15:18:25 -0800, Mark Borgerson
<(E-Mail Removed)> wrote:

>In article <(E-Mail Removed)>,
>(E-Mail Removed) says...
>> On Sat, 23 Jan 2010 13:17:45 -0800, Mark Borgerson wrote:
>>
>> >In article <(E-Mail Removed)>, (E-Mail Removed)
>> >says...
>> >> Mark Borgerson <(E-Mail Removed)> writes:
>> >>
>> >> > In article <(E-Mail Removed)>, (E-Mail Removed)
>> >> > says...
>> >> >> Mark Borgerson <(E-Mail Removed)> writes:
>> >> >> You seem to be assuming that the compiler emits machine code that
>> >> >> is in the same order as the corresponding C code, i.e. that the
>> >> >> call to Markend() will occur at the end of MoveMe(). This is not
>> >> >> a good assumption.
>> >> >
>> >> > This would certainly be a dangerous technique on a processor
>> >> > with multi-threading and possible out-of-order execution.
>> >> > I think it will work OK on the MSP430 that is the CPU where
>> >> > I am working on a flash-burning routine.
>> >>
>> >> Threading and out-of-order execution has little if anything to do
>> >> with it. The issue is the order of the code emitted by compiler,
>> >> not the order of the code's execution.
>> >>
>> >But woudn't an optimizing compiler generating code for a
>> >complex processor be more likely to compile optimize in
>> >a way that changed the order of operations? I think
>> >that might apply particularly to a call to a function
>> >that returns no result to be used in a specific
>> >place inside the outer function.

>>
>> Ben quite correctly brought you up short on the right point.
>> Your example was, just to refresh ourselves:
>>
>> >: int MoveMe ( ...., bool findend ) {
>> >: if ( !findend ) {
>> >: // do normal function stuff
>> >: } else
>> >: Markend();
>> >: }

>>
>> Let's divert from this for a moment and take the case of a
>> for-loop in c. It looks like:
>>
>> >: for ( init-block; condition; iterate-block )
>> >: body-block;

>>
>> A compiler will often translate this into this form:
>>
>> >: init-block;
>> >: goto A;
>> >: B: body-block;
>> >: C: iterate-block;
>> >: A: if ( condition ) goto B;
>> >: D:

>>
>> (The reason for the C label is to support the continue-
>> statement and the reason for the D label is to support a
>> break-statement, of course.)
>>
>> The straight interpretation would have been more like this:
>>
>> >: init-block;
>> >: A: if ( !condition ) goto D;
>> >: B: body-block;
>> >: C: iterate-block;
>> >: goto A;
>> >: D:

>>
>> But note that the execution of the for-loop's main body,
>> presumed by the compiler to have "many iterations" as a
>> reasonable guess, includes execution for the "goto A"
>> statement in each and every iteration. But so is, in effect,
>> the conditional test, too. In other words, it takes longer
>> to execute the body, even if that only means the execution of
>> one jump instruction. It's more efficient to redesign the
>> model used by the compiler to the first example I gave,
>> merely because the c compiler takes the position that the
>> added one-time execution of the first "goto A" will be the
>> lower cost approach (which it almost always will be.)

>
>I've also run across main processing loops such as
>
>void MainLoop(void)
> while(1){
> get user input
> execute commands
> }
> MarkEnd();
>}
>
>where MarkEnd doesn't appear in the generated machine
>code, because the compiler, even at lowest optimization
>setting, recognizes that the code after the loop
>will never get executed.


Yes, of course. That is another possibility. The intended
function may be essentially the "main loop" of the code and
as such never returns. However, whether or not MarkEnd()
were optimized out, it wouldn't ever get executed anyway. So
you'd never get the address stuffed into something useful...
and so it doesn't even matter were it that the compiler kept
the function call. So it makes a good case against your
approach for an entirely different reason than optimization
itself.

>> Now let's assume that the compiler takes the position that
>> the first case of an if-statement section is the more
>> frequently travelled one. In other words, when the
>> conditional case is executed, it will more often be "true"
>> than "false." The model used might very well then be to
>> convert:
>>
>> >: if ( condition )
>> >: s1-block;
>> >: else
>> >: s2-block;

>>
>> into:
>>
>> >: if ( !condition ) goto A;
>> >: s2-block;
>> >: goto B;
>> >: A: s1-block;
>> >: B:

>>
>> This provides s1-block execution with one less jump and
>> therefore lets it execute slightly faster with the idea that
>> it is the preferred path.
>>
>> So let's revisit your example again in this light:
>>
>> >: int MoveMe ( ...., bool findend ) {
>> >: if ( !findend ) {
>> >: // do normal function stuff
>> >: } else
>> >: Markend();
>> >: }

>>
>> This _may_ be taken by a c compiler to be:
>>
>> >: int MoveMe ( ...., bool findend ) {
>> >: if ( findend ) goto A;
>> >: Markend();
>> >: goto B;
>> >: A: // do normal function stuff
>> >: B:
>> >: }

>>
>> Leaving your function call to Markend not exactly where you'd
>> have liked to see it occur.

>
>That could certainly occur. I would be interested in the logic
>that could come to the conclusion that one or the other
>of the branches would be more likely to occur.


I wasn't suggesting that the optimizer includes a feature
where it "tries" to adduce the likelihood. I was suggesting
the idea that the compiler writer makes the 'a priori'
decision that it is.

Think of it this way. Ignorant of application specific
information, the compiler writer has two options to take when
considering the if..else case's approach. Regardless of
which way the compiler author chooses, one of the two blocks
will get a run-time preference. So, does the compiler author
_choose_ to prefer the if-case or the else-case? Without
knowledge, which way would _you_ decide to weigh in on?
Either way you go, you are making a choice. No escaping that
fact.

Now, the Bulldog compiler provides a way for the author of
the code to supply known information _or_ to use run-time
profiling to provide that information, automatically. But
I'm not talking about this case. That's for another
discussion. I only pointed that out for leisure reading. Not
as a point in this specific discussion.

>I guess the
>compiler could check all the calls to MoveMe and compare the
>number of times the findend parameter was true and false. However that
>might be pretty difficult if a variable was used.


Run-time profiling could provide that information. But that
wasn't anything I wanted you worrying over in this talk. It
distracts from the central point -- which is that a compiler
writer, sans application knowledge and sans anything in the
compiler or compiler syntax provided to the application coder
to better inform him/her about which way to go, must choose.
Either prefer the if-case or prefer the else-case. There is
no other option. So which way would you go?

>Still, a good reason, as I've said in other posts, to look
>at the resulting assembly langauage. I did it for one
>MSP430 compiler, and it worked the way I wanted. YMMV.


Indeed. I think the point here is that one is left entirely
to the vagaries of the compiler author. And on that point,
they may decide to go either way. There is NOTHING in the c
language itself to help them decide which is better.

>I wonder how many compilers would make that kind of optimization
>and under which optimization settings.


I think this question is moot. The point I was making
remains even _without_ optimizations that may help inform the
compiler about frequency of execution. So there is no need
to argue this point.

>> An old book you can pick up talking about a method used to
>> _explicitly_ inform the compiler about statistics of branch
>> likelihoods is the Ph.D. thesis by John Ellis:
>>
>> http://mitpress.mit.edu/catalog/item...d=5098&ttype=2
>>
>> Worth a read, some snowy day.

>
>Those are pretty rare in Corvallis. Only one or two so far this winter.
>Now, rainy days----those I get in plentitude!
>
>Mark Borgerson


Hehe. I live near Mt. Hood at an elevation of about 1000'
ASL. So I get three feet of snow and ice, from time to time.
I've had to use my JD 4320 tractor on more than one occasion!


Jon
 
Reply With Quote
 
Mark Borgerson
Guest
Posts: n/a
 
      01-24-2010
In article <(E-Mail Removed)>,
(E-Mail Removed) says...
> On Sat, 23 Jan 2010 15:18:25 -0800, Mark Borgerson
> <(E-Mail Removed)> wrote:
>

<<SNIP discussion of unpredictable, but legal, compiler behavior>>
> >
> >I've also run across main processing loops such as
> >
> >void MainLoop(void)
> > while(1){
> > get user input
> > execute commands
> > }
> > MarkEnd();
> >}
> >
> >where MarkEnd doesn't appear in the generated machine
> >code, because the compiler, even at lowest optimization
> >setting, recognizes that the code after the loop
> >will never get executed.

>
> Yes, of course. That is another possibility. The intended
> function may be essentially the "main loop" of the code and
> as such never returns. However, whether or not MarkEnd()
> were optimized out, it wouldn't ever get executed anyway. So
> you'd never get the address stuffed into something useful...
> and so it doesn't even matter were it that the compiler kept
> the function call. So it makes a good case against your
> approach for an entirely different reason than optimization
> itself.


Well, I wuould not dream of using this approach on a function
that never returns. OTOH a flash-update routine had better
return, or it won't be particularly useful (unless your goal
is to test the write-endurance of the flash)
>

<<SNIP>>
> >> An old book you can pick up talking about a method used to
> >> _explicitly_ inform the compiler about statistics of branch
> >> likelihoods is the Ph.D. thesis by John Ellis:
> >>
> >> http://mitpress.mit.edu/catalog/item...d=5098&ttype=2
> >>
> >> Worth a read, some snowy day.

> >
> >Those are pretty rare in Corvallis. Only one or two so far this winter.
> >Now, rainy days----those I get in plentitude!
> >
> >Mark Borgerson

>
> Hehe. I live near Mt. Hood at an elevation of about 1000'
> ASL. So I get three feet of snow and ice, from time to time.
> I've had to use my JD 4320 tractor on more than one occasion!
>
>

Mark Borgerson

 
Reply With Quote
 
Grant Edwards
Guest
Posts: n/a
 
      01-24-2010
On 2010-01-23, BGB / cr88192 <(E-Mail Removed)> wrote:
>
> "Grant Edwards" <(E-Mail Removed)> wrote in message
> news:hjdjjj$njp$(E-Mail Removed)...
>> On 2010-01-23, BGB / cr88192 <(E-Mail Removed)> wrote:
>>
>>> in this case, it might actually be better advised to generate
>>> the function as a chunk of arch-specific ASM or machine code
>>> (ASM is preferable IMO, but requires an assembler...), which
>>> could then be located wherever (such as the heap).

>>
>> IMO, the "right" thing to do is to tell the compiler to put
>> the function into a separate section and then have it linked
>> so that it's "located" to run in RAM at the proper address but
>> stored in ROM.
>>
>> That way you know the code will work correctly when it's run
>> from RAM. Defining approprate symbols in the linker command
>> file will allow the program to refer to the start and end of
>> the section's address in ROM.

>
> this is a little closer to the second option, of having a
> secondary image file embedded as data...


Yup, it's pretty much exactly that.

>> The OP needs to spend some time studying the manuals for his
>> compiler and linker.

>
> this is, assuming the linker or image format actually supports
> the "separate section" idea...


Every C compiler/toolchain I've used for embedded systems
development for the past 25 years supported things like that.
If his tools don't support multiple sections, then the first
order of business is to find a decent toolchain.

> dunno about ELF,


ELF supports multile sections, and I've done exactly such
things with ELF-based toolchains (Gnu binutils and GCC) when
working on stuff like bootloaders where the memory map changes
completely part-way through the program as the memory
controller gets configured.n

> but PE/COFF would not support this, since it would require
> breaking some of the internal assumptions of the file format
> (for example, that the image is continuous from ImageBase to
> ImageBase+ImageSize, ...).
>
> ELF may have similar restrictions (actually, I think most ELF
> images are position independent anyways,


That depends on the compiler options and linker command file.
In my experience, "executable" ELF files on embedded systems
(images that are ready to load into RAM and run) are generally
not relocatable.

> can't say so much about other file formats though...


The COFF-based toolchains I've used all seem to support
multiple sections, but that may have been due to
vendor-specific extensions.

--
Grant


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Preferred Size, Minimum Size, Size Jason Cavett Java 5 05-25-2008 08:32 AM
Getting picture size/setting window size jodleren Javascript 2 02-15-2007 12:35 PM
mega pixels, file size, image size, and print size - Adobe Evangelists Frank ess Digital Photography 0 11-14-2006 05:08 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Passing a C++ object's member function to a C function expecing a function pointer! James Vanns C++ 7 01-21-2004 02:39 AM



Advertisments