[comp.sys.cbm] Overwriting the stack

john13@garfield.MUN.EDU (John Russell) (12/20/88)

This is something that has always bothered me. A standard trick I used to use
many years ago on the C64 was the following (in PAL notation, and probably
not terribly accurate):

10 *= $0100	; beginning of stack
20 .byte 02	; fill stack with $0202 addresses
30 .if *-$0203: .goto 20	; loop until PC reaches $0203
40 [ boot code ]	; located at $0203, executed when LOAD does an RTS

By using this I was able to create all sorts of programs that would auto-run
on being loaded ,8,1. But what puzzles me is how the program loading routine
manages to read in bytes that completely corrupt the stack, and still manage
to only return (ie execute an RTS) when the program load is finished.

This would seem to indicate to me that the main disk-load routine never
does any subroutine calls (eg GETIN). Is that the way it works?

John
-- 
"Version 2.0 is advertised as supporting cursor keys."
	    -- somewhat left-handed endorsement of a Mac word-processor :-)

elg@killer.DALLAS.TX.US (Eric Green) (12/20/88)

in article <5043@garfield.MUN.EDU>, john13@garfield.MUN.EDU (John Russell) says:
> By using this I was able to create all sorts of programs that would auto-run
> on being loaded ,8,1. But what puzzles me is how the program loading routine
> manages to read in bytes that completely corrupt the stack, and still manage
> to only return (ie execute an RTS) when the program load is finished.
> 
> This would seem to indicate to me that the main disk-load routine never
> does any subroutine calls (eg GETIN). Is that the way it works?

The main disk-load routine DOES do a subroutine call to GETIN, but
that doesn't matter. Here's the basic LOAD loop:

loop:
  jsr get_from_disk
  if eof, exit
  sta (buffer),y
  jsr increment_buffer
  goto loop

Your stack usage looks like:

$0200
...
<address: return from LOAD>
<address: GETIN, increment_buffer>
...
$0100

The cassette loading routine looks similiar.

When you jsr the get_from_disk or increment_buffer, it pushes the
return address on the stack, overwriting any $0202 that may have been
put there by the last "sta". So there's no problem with your return
address being evaporated. The only time there would be a problem would
be if the "sta" was within a subroutine, in which case it COULD
scribble on its return address (e.g. if you combined the sta
(buffer),y and the increment_buffer subroutine into a single
"store_byte" subroutine, you'd scribble over your return address).
Commodore's routine in the C64 doesn't do that, but I seem to recall
that you're not supposed to scribble over the stack in the C128 (in
128 mode). Since the 128 has a boot sector setup for disk drives,
that's not a real restrictive problem.

--
Eric Lee Green    ..!{ames,decwrl,mit-eddie,osu-cis}!killer!elg
          Snail Mail P.O. Box 92191 Lafayette, LA 70509              
Netter A: In Hell they run VMS.
Netter B: No.  In Hell, they run MS-DOS.  And you only get 256k.