Path: utzoo!attcan!uunet!munnari.oz.au!csc.anu.oz.au!csc3.anu.oz.au!anucsd!neccan!peter From: peter@neccan.oz (Peter Miller) Newsgroups: comp.lang.c Subject: Re: Self-modifying code Message-ID: <829@neccan.oz> Date: 9 Oct 90 01:29:47 GMT References: <1990Oct08.183922.12541@eecs.wsu.edu> Organization: NEC Information Systems Australia, Canberra Lines: 50 in article <1990Oct08.183922.12541@eecs.wsu.edu>, rdubey@eecs.wsu.edu (Rakesh Dubey - grad student) says: > Though I *think* you can do it, but you shouldn't be needing > such tricky/unreliable kind of stuff. I have used self-modifying code on a number of occasions, and while I don't advise its use as a general rule, I think it has a place in every programmers box of tricks. Examples: 1. On a Z80 I wrote some code which used a NMI (non-maskable interrupt). The problem was that the Z80 has no 16-bit indirect load opcode, only 8-bit indirect, and (for various reasons which would take ages to describe) it was not avoidable to do the 16-bit indirect load. Murphy's Law sprang into play, (I was doing the 16-bit indirect as 2 8-bit indirects) and the NMI, every few hours, fell beween the 2 8-bit indirects, giving an impossible result and causing all sorts of weird behaviour. I solved it by declaring an array of 4 chars and setting it to the absolute load opcode, the 16-bit address, and an rts opcode. The I cast the array pointer to a function pointer and called it. Viola, 16-bit indirecting function. char barf[4]; barf[0] = opcode ld hl,N barf[1] = addr; barf[2] = addr>>8; barf[3] = opcode rts result = (*(char *(*)())barf)(); 2. On a pseudo-emacs editor I wanted real regular expressions, So I wrote a RE compiler in Lisp which produced lisp as output, and promplty executed that output. Lisp makes self-modifying code easy. 3. A very long time ago I used an apple ][ (skeleton rattles). Disassembling the disk driver is enlightening. The disk io needed every last cycle from the machine, and so the code first calculated the hardware's memory addresses and poked it into the absolute load instructions for the rest of the disk io code, thus getting better performance from the code (abs, rather than register indexed) and freeing up a register, too. 4. At some point, I realized that using a compiler is rather like self-modifying code. The compiler, itself a binary data file, chews on a text file and makes a binary data file. When we run the program we just compiled, we are asking the OS to load a binary data file and leap into it. Regards Peter Miller UUCP uunet!munnari!pdact.pd.necisa.oz!pmiller /\/\* CSNET pmiller%pdact.pd.necisa.oz@au ACSnet pmiller@pdact.pd.necisa.oz Disclaimer: The views expressed here are personal and do not necessarily reflect the view of my employer or the views or my colleagues. D