Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!elroy.jpl.nasa.gov!swrinde!mips!bridge2!jarthur!uunet!cbmvax!daveh From: daveh@cbmvax.commodore.com (Dave Haynie) Newsgroups: comp.sys.amiga.programmer Subject: Re: Self modifying code Message-ID: <22018@cbmvax.commodore.com> Date: 29 May 91 23:34:23 GMT References: <5005@orbit.cts.com> <1991May28.120630.10150@cs.umu.se> Reply-To: daveh@cbmvax.commodore.com (Dave Haynie) Organization: Commodore, West Chester, PA Lines: 52 In article <1991May28.120630.10150@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes: >Ok, I have heard before that you should not use self modifying code. >Can anybody give a good reason for this, besides it being bad programming >pratice. Because it goes against the basic design of the 680x0 processor family. In the 680x0 family, you have code and data spaces. Very often these are the same memory, sometimes they aren't. If they aren't, modifications to data space are not reflected in code space. >Could it be that data written to an address that is also in cachememory >will update the memory, but not the cache? Exactly. Consider a chunk of code that gets modified to do a two things, Thing-A and Thing-B. You run it through on your A500, it does Thing-A, hits the modification routine, then it does Thing-B. Great. Only, once its released on the market, I buy it and run it on my A3000. The code romps along, does Thing-A, gets to the modification routine, then, whoops, it does Thing-A again, because while the code in main memory now does Thing-B, the code in the 68030's I-Cache still does Thing-A. >Consider for instance that I would like to write a fast completely >unwinded linedrawing routine and wrote code for drawing one pixel. >Then when the program start, I would allocate memory for 320 such routines >and putting 320 copies of my routine there. Would this be considered as >selfmodifying code, and therefore forbidden? In a sense, though it's not the worst offender. The main problem is changing data space into code space. LoadSeg() knows how to do this. You don't, unless you explicitly clear caches after any such transform (which you can only do in 2.0, by the way). If you do something like my example, you're certain to fail with a large enough cache, since you cache code, immediately change it, then execute it again. Another problem may be stale caches. If you allocate a chunk of memory and build some code in it, you have to explicitly clear the system cache before executing code, otherwise you may find you are executing code that used to be in that there from another task, since to the CPU, that memory is in data space when you act on it. >If so, compare it to when the OS is loading a program that contains >non-PC relative references to itself which will have to be rewritten >depending on the address the code was loaded to. The OS knows the proper steps to take to do the various code space transforms and cache clears properly (in reality, since main memory is unified I and D memory, the only thing that's really done is cache update). There are apparently 2.0 calls that allow a program to Do The Right Thing. The software folks could cover this in greater detail. -- Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests" {uunet|pyramid|rutgers}!cbmvax!daveh PLINK: hazy BIX: hazy "That's me in the corner, that's me in the spotlight" -R.E.M.