Thread: Breaking out of a function properly?

  1. #1
    Registered User
    Join Date
    Apr 2021
    Posts
    26

    Breaking out of a function properly?

    So I decided to try a different approach regarding the code and before I show a few examples of my coding, I want to get back to one bit of 680x coding that has me scratching my head looking for a clean way to rewrite it.

    There are seven instances in the code, where the subroutine (or function) is called, and if one conditional is met, it makes a small jump to the return call. If the conditional goes to the "else" case, there are a couple instructions that effectively discard the saved return address, followed by a jump to a completely different program section.

    Here's what I mean:

    Code:
      $FC80    LDA A   #$01
               STA A   $B7
               STA A   $C9
               LDA A   #$10
               STA A   $BE
               JSR     $F12C
               LDA A   $B7
               BLE     $FC96
               INS    
               INS    
               JMP     $EE0A
      $FC96    CLR     $C9
               RTS
    So, if address $B7 is less than or equal 0, then it hops forward to the ending instructions of the subroutine / function, while the "else" case is the next instruction.

    The two INS instructions nudge the stack pointer to tell the CPU to forget the subroutine it was currently executing and jump off to the code at $EE0A.

    How would I approach this in C++ without risking the stack filling up with abandoned subroutine calls? I already have a rough translation ready to shine up into proper C++, it's just the jump that remains, and I can get several functions out of the way once i know the answer.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,323
    Pardon me, but I thought you wanted to port over to C, not C++.

    As for your question: maybe a possible approach in C or C++ would be to return a value, and based on this value the caller decides what to do, e.g., call another function.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2021
    Posts
    26
    ...I didn't realize there was that much difference between the variants - given how little I know about the C languages, I may have posted my original question in the wrong forum?

    Regardless, as Arduino is a possible destination platform for this code I'm working on, I realize I need to make sure my code follows C++ and not just 'vanilla' C.

    An alternate approach would be to copy the conditional out of the function into the main program flow. That'll be quite a task, as this little snippet of code alone is called up no less than 29 times.

    Another routine alone contains no less than three of the breaks in question and is itself called 16 times.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,655
    You have something like this
    Code:
    void foo_FC80 ( ) {
      if ( ... ) {
      } else {
        // JMP     $EE0A in the stack frame of baz()
      }
    }
    void bar() {
      foo_FC80();
      // more stuff
    }
    void baz {
      // stuff
      bar();
      // the stack would point to this function.
      // Where is JMP     $EE0A in relation to the rest of the code in this function?
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Apr 2021
    Posts
    26
    Salem - THANK YOU for the prompt to look at the code at $EE0A...!

    Had a light-bulb moment (and a 100-watt grin on my face atm)

    I now realize what's happening - the code at EE0A displays a number I now realize (from the sparse documentation I have) is an error number, then the program flow returns to the top of the main loop.

    I'm now 99% certain I know what I need to do, but first, a general question on conditionals:

    Am I correct that:

    if ( conditional ) label; is like a IF... GOTO in Basic

    and

    if ( conditional ) function(); is like a IF... GOSUB in Basic?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,655
    Yes, that's pretty much how it would work.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2021
    Posts
    11
    Not quite. The statement in C/C++ is also called "goto", but in lower case.
    Code:
        if (x < 5) goto SKIP;
        std::cout << "Didn't skip." << std::endl;
    SKIP: ; // label on an empty statement
    That's an equivalent to an if statements using goto in C++. There's not much point in that in this century. C++ has more restrictions on where you can jump to than C did. A goto into a braced block that has initialization (like local variables inside the block) was undefined behavior in C but is disallowed in C++.

    If you want a structured type of abrupt transfer of control, look into exceptions in C++ (if your environment supports them) or the setjmp/longjmp functions in C or C++.

  8. #8
    Registered User
    Join Date
    Apr 2021
    Posts
    26
    The approach I plan to take within the function is to set the variable 'error' if the conditional is met that would have triggered the jump to the INS instructions, and use the 'else' part of the conditional for the 'graceful' return.

    Then, upon returning from the function, I will add a conditional to jump to a section I will label errorTrap if the variable 'error' is NOT zero.

    So, I'm thinking something like this:

    Code:
    int LB_FC80
    {
    var_B7 = 0x01;
    var_C9 = 0x01;
    var_BE = 0x10;
    LB_F12C(); 
    // the function at $F12C is a time delay
    // Number carried from var_BE determines delay length
    if ( var_B7 > 0x00 ) error = 0x0A;
    // conditional operator and normal / else cases flipped for better program flow
    // var_B7 is modified in the background through an interrupt-driven routine
    else var_C9 = 0x00
    }

  9. #9
    Registered User
    Join Date
    Apr 2021
    Posts
    26
    Followup: I have now eliminated all seven 'emergency exit doors' from the code.

    The more I dig, the more I am amazed the original code works as well as it did on the original hardware.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function not behaving properly
    By Moksha in forum C Programming
    Replies: 9
    Last Post: 01-19-2017, 01:50 PM
  2. How to properly use a function?
    By Who in forum C Programming
    Replies: 2
    Last Post: 02-01-2013, 03:25 AM
  3. advise on how to properly use pow function
    By libchk in forum C Programming
    Replies: 12
    Last Post: 08-31-2011, 12:50 AM
  4. How to properly use a C function?
    By John_L in forum C Programming
    Replies: 4
    Last Post: 05-30-2008, 02:01 AM
  5. Loop doesn't seem to function properly
    By TeQno in forum C++ Programming
    Replies: 1
    Last Post: 01-31-2005, 05:25 PM

Tags for this Thread