Automatic variables (local variables and parameters to called functions) have to be stored somewhere. That somewhere is on the stack (or in registers, but that's nor important right now).
Here's a little simplified stack annotation for how your program runs:
int main(void)
{
// [_start+0x040 ]
// This is just the address of some code just after the code that called main.
// You immediatly call make_text, so lets go there.
char *make_text(void)
{
// [_start+0x040, main+0x004]
// this is the address within main that make_text returns to
char txt[MAXLEN];
// [_start+0x040, main+0x004, txt[MAXLEN-1], ..., txt[0] ]
return txt;
// This empties this function's data and pops the return address into
// the instruction pointer.
}
char *s = make_text();
// [_start+0x040, &txt[0] ]
// Now, back in main we have an address to something that is not on the stack
// anymore.
// Random things happen to memory that used to be part of the stack.
puts(s);
// [_start+0x040, &txt[0], main+0x008 ]
// puts() here tries to print a string containing random data which also happens
// to be the same memory that puts is trying to use as its local variables.
getch();
// getch() is the only part that probably worked