Author Topic: Executing "ret" twice?  (Read 7450 times)

0 Members and 1 Guest are viewing this topic.

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Executing "ret" twice?
« on: October 10, 2010, 07:55:06 am »
I've stumbled across another problem - how would I do a "double" ret command?
Let me explain:
Code: [Select]
Label1:
   call   label2
   ret                ; Let's call this one "ret%" This will go to where I want!

Label2
   ret                ; I want this "ret" to go to the same 'place' as "ret%".
Or, to make things more general:
Code: [Select]
Label1:
Call Label2
(......)        ;[1]

Label2:
Call Label3
ret             ;[2] Will take it back to [1].

Label3:
Call Label4
ret             ;[3] Will take it back to [2].


Label4:
Call Label5
ret             ;[4] Will take it back to [3].


Label5:
ret             ;[5] Will take it back to [4].
In the latter example, I want the ret from [5] not to go back to [4], but, lets say, to [1].
Is it possible to set things up in such way that a "ret" command will do that?
I don't know the specifics, but the addres from which you use "Call" from gets stored in a  stack, right?
So would it be possible to "Pop" that stack, so that a "ret" will take it back more than one 'step'?
From what I've  read, "POP   PC" would do that. :P Though I've  tried that and then my assembles gives an error, so I guess things aren't that simple.
Thank you!
« Last Edit: October 10, 2010, 08:23:42 am by Jerros »


79% of all statistics are made up randomly.

Offline jnesselr

  • King Graphmastur
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2270
  • Rating: +81/-20
  • TAO == epic
    • View Profile
Re: Executing "ret" twice?
« Reply #1 on: October 10, 2010, 08:19:46 am »
Yeah, iirc, the last address is stored on the stack.  Try a pop into hl and then go to that address.

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Re: Executing "ret" twice?
« Reply #2 on: October 10, 2010, 08:40:41 am »
Yeah, iirc, the last address is stored on the stack.  Try a pop into hl and then go to that address.
Ehrm, as in:
Code: [Select]
Label1:
   Call   Label2
   (...)

Label2:
   Call   Label3
   ret                  ; <-- isn't neccarery, since it will nver get executed, right?

Label3:
   POP   HL
   ret                     ;<-- will go to label 1?
^That?

EDIT:
Doesn't work.
I'm more braindead than you can imagine - could you elaborate what you meant with:
Try a pop into hl and then go to that address.



Thanks for the reply!
« Last Edit: October 10, 2010, 08:43:39 am by Jerros »


79% of all statistics are made up randomly.

Offline jnesselr

  • King Graphmastur
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2270
  • Rating: +81/-20
  • TAO == epic
    • View Profile
Re: Executing "ret" twice?
« Reply #3 on: October 10, 2010, 09:55:25 am »
Yeah, not quite.  See, when you do a call, and I can't remember the exact addresses, but I think it stores the byte right after it, so that it would be on the ret or something. I'm not real sure, some other asm programmer could help you a little better.  I've always just used ret.  If you have a debugger, try following where the call is going, and if you can, what is on the stack.  I believe the TI-83 SDK has one.

Also, btw, if it went to the byte to label1, it would be the call for label2, which would call it, and then that would be an infinite loop.

Try this as a completely new program:
Code: [Select]
Label1:
push Label2
ret

Label2:
ret
This should exit the program because you are pushing the location of Label2 onto the stack, and then returning to it. Not sure, though. If that doesn't work, just push two zeros onto the stack, and run it with a ret. That should reset your calc, so beware.

SirCmpwn

  • Guest
Re: Executing "ret" twice?
« Reply #4 on: October 10, 2010, 10:03:07 am »
That looks like it will work at first glance, but I don't konw why it isn't.  This is how calls work:
Code: [Select]
9D95h:   Label1:
9D95h:   call Label2   // 1. Pushes 9D97 to the stack, loads 9D98 into PC
9D97h:   ret  // 5. This executes.
9D98h:   Label2:
9D98h:   call Label3  // 2. This loads 9D9B onto the stack (the stack at this point: 9D9B, 9D97) and loads 9D9C into PC
9D9Bh:   ret
9D9Ch:   Label3:
9D9Dh:   pop hl  // 3. This removes the last stack entry (the stack at this point: 9D97)
9D9Eh:   ret  // 4. This does the equivalent of POP PC (PC now equals 9D97)

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Re: Executing "ret" twice?
« Reply #5 on: October 10, 2010, 10:27:05 am »
That looks like it will work at first glance, but I don't konw why it isn't.  This is how calls work:
I don't know why it isn't either, haha.
Try this as a completely new program:

Code:
Label1:
push Label2
ret

Label2:
ret
This should exit the program because you are pushing the location of Label2 onto the stack, and then returning to it. Not sure, though. If that doesn't work, just push two zeros onto the stack, and run it with a ret. That should reset your calc, so beware.
But does label 2 get executed now?
Doesn't look like it...
ret  // 4. This does the equivalent of POP PC (PC now equals 9D97)
So... isn't it possible to do POP PC then?
Because POP HL just pops... HL, not PC right?
It doesn't seem to work though...
« Last Edit: October 10, 2010, 10:59:12 am by Jerros »


79% of all statistics are made up randomly.

SirCmpwn

  • Guest
Re: Executing "ret" twice?
« Reply #6 on: October 10, 2010, 11:05:20 am »
ret IS pop pc.
pop hl pops hl.

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Re: Executing "ret" twice?
« Reply #7 on: October 10, 2010, 11:48:41 am »
ret IS pop pc.
pop hl pops hl.
But... I want to pop PC twice with one Ret command...
Or at least do 2 pops and THEN peform the next line of code.
I suck at making myself clear. Q_Q


79% of all statistics are made up randomly.

SirCmpwn

  • Guest
Re: Executing "ret" twice?
« Reply #8 on: October 10, 2010, 11:55:41 am »
Err...
ret \ ret would pop pc twice, but the first time you pop pc, the next line will not execute, because PC will be elsewhere.  Pop is not exclusive to variables, they are all on the stack together.  For instance:
Code: [Select]
push hl
push bc
pop hl
pop bc
This will swap the values of hl and bc.  Therefore, if (9D95:) call xxxx pushes PC to the stack and loads xxxx into pc, the stack looks like this:
9D95
Then, if you pop hl, you can no longer return to that location unless you push it back.  Look at this:
Code: [Select]
Label1:
push Label1
jr Label2
This is the equivalent of call Label2, just with more bytes.

Offline mapar007

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 550
  • Rating: +28/-5
  • The Great Mata Mata
    • View Profile
Re: Executing "ret" twice?
« Reply #9 on: October 10, 2010, 12:21:33 pm »
POP HL \ ret should work, Jerros. Maybe the fault is elsewhere? Do you mind posting the code fragment involved?

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Re: Executing "ret" twice?
« Reply #10 on: October 10, 2010, 12:32:38 pm »
POP HL \ ret should work, Jerros. Maybe the fault is elsewhere? Do you mind posting the code fragment involved?
I'll just try again.
The code fragment considered is BIG (over 600 lines + lots of calls and stuff) so I dont want to bother you with that ^_^.
To give more detail of what I'm trying:
Code: [Select]
Label1:
(...)
   CALL   Label2
(...)                            ; <-- must get executed after the RET*

Label2:
(...)
   CALL   label3
(...)                            ; <-- A normal Ret in Label 3 will cause this to be executed. I don't want that :P.
ret
Label3:
    b_call _GetCSC
    CP     skDel
    JP     Z, Quit
    JR     Label3
Quit:
   ret            ; and I want this RET* to go to Label1, NOT 2.
It's obvious that I should use a JP under "Quit" to go to where I want in Label1, though I have my reasons for it to MUST be a "ret"...
Err...
ret \ ret would pop pc twice, but the first time you pop pc, the next line will not execute, because PC will be elsewhere.  Pop is not exclusive to variables, they are all on the stack together.  For instance:
Code: [Select]
push hl
push bc
pop hl
pop bc
This will swap the values of hl and bc.  Therefore, if (9D95:) call xxxx pushes PC to the stack and loads xxxx into pc, the stack looks like this:
9D95
Then, if you pop hl, you can no longer return to that location unless you push it back.  Look at this:
Code: [Select]
Label1:
push Label1
jr Label2
This is the equivalent of call Label2, just with more bytes.
Wow! Thanks, I get it now :P
Though I can't experiment anymore today, I'll post as soon as I know more.


79% of all statistics are made up randomly.

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: Executing "ret" twice?
« Reply #11 on: October 10, 2010, 01:56:36 pm »
Actually, a call Label2 equivalent would look like this:
Code: [Select]
Label1:
  ld hl,ReturnLabel
  push hl
  jp Label2
ReturnLabel:

It won't be returning to Label1, it will return to the point after the call.
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

SirCmpwn

  • Guest
Re: Executing "ret" twice?
« Reply #12 on: October 10, 2010, 01:57:47 pm »
Thanks calc84maniac.

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Re: Executing "ret" twice?
« Reply #13 on: October 11, 2010, 06:58:03 am »
Actually, a call Label2 equivalent would look like this:
Code: [Select]
Label1:
  ld hl,ReturnLabel
  push hl
  jp Label2
ReturnLabel:

It won't be returning to Label1, it will return to the point after the call.
Thanks thanks thanks! :P
I'll try this as soon as possible. ^_^


79% of all statistics are made up randomly.

Offline Jerros

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 137
  • Rating: +9/-0
    • View Profile
Re: Executing "ret" twice?
« Reply #14 on: October 12, 2010, 03:41:29 am »
Figured it out ~
All I needed to do was pop HL enough times to return to where I wanted it to:
Code: [Select]
RetMoar:
POP HL
POP HL
ret
I just didn't knew how calls and stacks worked, but by putting all your advices together, I've got a pretty clear idea now, and managed to fix my own problem (albeit a noob problem).
Thank you all!

EDIT:
Or so I thought...
It seems that the number of POPs required varies the whole time, which is odd...
Do more lines get executed after the GetCSC if you press a button?
Like:
Code: [Select]
    b_call _GetCSC
    CP     skDel
    JP     Z, Quit
    (...)                            ; Can this get executed, even though you press the Del button?
                                      ; If that's true, things just've gotten much more complicated :c

Quit:
POP HL
POP HL
ret
« Last Edit: October 12, 2010, 04:06:28 am by Jerros »


79% of all statistics are made up randomly.