3

I am calling a PROC to test two values in assembly x86 16bits and then jump if the value is bigger than zero, so I am doing something like this:

TESTIT PROC
    CMP AX,1
    JG  FOO
    RET
TESTIT ENDP

FOO:
    ;do something
END FOO

MAIN:
    CALL TESTIT
    .EXIT
END MAIN

END

My questions is simple, how do I return back from FOO to the point in MAIN that called TESTIT. I do not want to perform a JMP from FOO to MAIN, as that will call TESTIT again. When I try to put RET at the end of FOO, the command window gets stuck with a blinking cursor.

Note: I know this can be achieved using the pseudo op .IF ... .ENDIF instead of JG but I want to try and achieve the same result without the pseudo op, which does some magic in the background I do not know how to achieve manually.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Related: [What if there is no return statement in a CALLed block of code in assembly programs](https://stackoverflow.com/q/41205054) is the opposite problem, but the answer explains that labels aren't special, and that `ret` is just `pop eip` so it needs the stack pointing to a return address. (which `jcc` doesn't push). – Peter Cordes Feb 20 '22 at 21:20

1 Answers1

8

FOO needs to be called as a subroutine. To do that, invert the logic of your jump, and use the CALL instruction to call FOO. Put a RET instruction at the end of the FOO routine.

TESTIT PROC
    CMP AX,1
    JLE  BAR
    CALL FOO
BAR:
    RET
TESTIT ENDP

FOO:
    ;do something
    RET
END FOO

MAIN:
    CALL TESTIT
    .EXIT
END MAIN

END
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501