This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Goto Label xxx in other file...

Dear all,
I have a question about jumping to some specific label in other file(in Keil C51 project)

Ex. In file A there is one label named _xxx. In file B can we use

goto _xxx

?
(maybe _xxx should be declared as extern, right ?)

The reason why I want this is: We did NOT want to do the tasks before label _xxx because they are wrong...! And unfornately file A is located in ROM and we can not modify it...

So we want to just jump to label _xxx and skip wrong codes....

  • More detailed information is:

    File A located in ROM

    ...   // wrong code here
    _xxx  // label
    ...   // OK code
    

    File B in RAM

    ccc   // corrected code here
    goto _xxx   // this can skip wrong code in File A
    

    Thus the calling sequence will be:
    - execute corrected code in File B
    - jump to ROM code labeled _xxx
    - execute OK code in File A

    Note: We still want to execute the remaining codes after label _xxx in ROM !!!

  • I'm a bit confused about your terminology.

    You use name "goto" which is a keyword in C. But this goto will not allow you to jump out of your current function, because of all issues with stack frames, auto variables, stack cleanup, register variables, ...

    For assembler, you can jump anywhere. Since the destination is a fixed location in ROM, you have to give the assembler code the absolute address.

  • Thanks for your opinion.(I guess I can use "goto" to jump out of current function...)

    Is there any way to solve this issue ?

    Absolute address of Label _xxx is known and can I use inline assembly in C51 to jump to this address ?

    Thanks in advance...

  • No, it wasn't an opinion, but a representation of limitations of the C goto mechanism. There is a "longjmp" functionality but that is also outside the scope of this issue.

    Assembler code can jump to anywhere in the code address space. You just have to make use of the correct absolute address which you might have picked up from listings/map files of the original ROM code.

    C code can perform a call (not jump) using a function pointer that have been set to the absolute address. But that requires that stack etc are properly setup and that your current C function perfectly matches all assumptions required at the "reception point". And that the called (not jumped) target never returns, or that it contains a code sequence that returns in a compatible way back to your C function - while still fullfilling all requirements/assumptions about used registers etc.

    My opinion is that performing "cut" and "paste" trying to reuse already existing binary code is best done from assembler where you have 100% control of every register etc before jumping into this address. The question here is if you have created a list of all requirements that needs to be fulfilled for this absolute jump to give the expected result.

    By the way - you have never mentioned if the code in ROM is compiled code from a C program or is created from hand-written assembler instructions. That makes a big difference when itemizing all requirements that needs to be fulfilled for this jump to give expected result.

  • And unfornately file A is located in ROM and we can not modify it
    assume file a contains
    void Ralph(void)

    change your calls in your code from
    Ralph();
    to
    RalphReplace();

    then write
    void RalphReplace(void)
    in your code

    STAY AWAY FROM GOTO!

    Erik

  • The code in ROM is compiled code from a C program.

    And the reason why I did not use the redirection way(like Erik said) is: what I want to call is NOT a function, but a piece of code segments in ROM. Thus I can not use RalphReplace() to replace Ralph() !

    I have one idea about this issue and maybe you all can give me some opinions...

    (1) create .a51 file where .a51 contains:
    - function C()
    - The function body of C() is only "jump to the specific absolute address"(I can get it in .m51 file)
    (2) add this .a51 to my project
    (3) declare function C() as "extern"
    (4) In File B, call C()...

    Is it possible to solve this issue ?

  • 2 considerations:

    a. What I want to call is NOT a function,but a piece of code segments
    b. If re-write RalphReplace() then I did NOT have enough code space for it

  • .... how are you going to get back?

    Erik

  • The ROM code is part of a function.

    Functions are called - not jumped to.

    This is important, because the last part of that function wants to do a return - and then it needs a return address.

    So you must call - not jump. Or manually set up a return address.

    Next thing. That part of the already existing code expects that that there are parameters, and local variables (maybe on stack - maybe modified into global variables). Your stub function must make sure it fulfills these requirements too.

    Third - because you have a label in the assembly listing doesn't mean that you have a "clean break". That function may expect a number of values in registers (or in local or global variables). This must be matched by your stub function.

    Fourth - if the function did pass anything on stack, then it would probably assume that the caller clears the stack after the function returns.

    Fifth ...

    Do you get the idea? Knowing an address in ROM does not make it easy to jump/call to that address and get a good result. You must be very familiar with all requirements. But if you was very familiar with them, you would not have created this thread in the first place. And we can't help you, since we can't see your code. So you have a bit of a gordian knot here.
    - if you know the requirements, you don't need to ask.
    - if you need to ask, you don't have the requirements to get this to work.

    For this to work, you must be able to reverse-engineer the exact behaviour of the relevant part of the ROM code. And then make an assembly stub function that recreates the required "sandbox".

  • a. What I want to call is NOT a function,but a piece of code segments

    what is "a piece of code segments"

  • What I want to call is NOT a function,but a piece of code segments

    OK. Exactly what stops you from placing the code you want to just to inside a FUNCTION!?
    Place the function at an absolute location and branch to it (that is a call). What's the problem? Why mess up your life?

  • <to self> Ditch the tome I wrote describing how to utilize post-processing tools to generate what you need.</to self>

    The mere fact that you're a taker, not a learner, demonstrates that you are ill-equipped to understand how to achieve it. Takers lose, learners win.

  • Thanks for all your comments first !

    Why I wanted to do so originated from the customer report issue - our firmware code failed if using downgrade product. Then We found if we can "skip" some tasks then this issue is solved.
    But unfortunately these codes are all in ROM, we can not modify it ! So my first idea is to jump to some specific address in ROM and this can skip these tasks if available...

    Assume N means "NG" code and O is "OK" code. Then N is small(in code size) and O is big(in code size) Besides, N and O are not functions,just code segments.

    Code in ROM

    void main()
    {
    // code N here
    _xxx:  // label here
    // code O here
    // code O here
    // code O here
    // ...
    
     while(1)
     {
      // polling to receive command,execute command...
     }
    
    }
    

    If we use new function to replace the O part,then it will consume much code space. Besides we want the code transfer to the while(1) part to (polling,receive,and execute requests),like the normal case...

    That is the reason why I want to try "jump" first because in this case:
    #1 no need to pass parameters and local variables
    #2 the "requirements" in this situation might be little(code N is simple)

    I will try to reverse-engineer the exact behaviour of the relevant part of the ROM code then decide the better way...

    Thanks !

    liaoo

  • But unfortunately these codes are all in ROM, we can not modify it !

    How then will you then implement your "jump" change? I don't understand.