A friend of mine used to program the PDP-8 a lot. The PDP-8 didn't have a stack; to call a subroutine, the JMS FOO instruction would store the return address at (the effective address computed from) FOO, then continue execution at the following word. So to return, the called subroutine would do an indirect jump using the address stored in the memory word before the beginning of its code.
I was surprised when he told me how people normally passed arguments. They would put them after the JMS instruction in the caller. So, the callee would indirect from the "return address" stored in FOO to retrieve its arguments, incrementing the return address after each one. So the code to call FOO with arguments 1 and 2 would be (in Intel syntax)
JMS FOO
DW 1
DW 2
[code to run after returning]
Mark Smotherman explains this in more detail, using PDP-8-compatible syntax, in
https://people.computing.clemson.edu/~mark/subroutines/pdp8.....
It seems sort of intuitive to do things this way; if you're writing atan2(3, 4), it's nice to be able to translate this to
jms atan2
3
4
rather than, say, mov $3, %rdi; mov $4, %rsi; call atan2.
Maybe someone had this habit in their assembly and adapted it to the 8086's calling convention by inserting MOVs and a JMP instruction?
You can also imagine that a compiler might be somewhat simpler if it generated code in the order in which it encountered the expressions. Gas lets you switch back and forth between .text and .data, so that if your compiler does this, you still don't have to insert JMP instructions. However, a few years ago when I wrote Ur-Scheme, I did do this for lambda expressions: the code for the lambda expression is generated inline in the middle of its containing code, which then has to contain a jump past it.