Self Modifying Code

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Self Modifying Code

Post by julie_m » Tue Jul 07, 2020 8:40 pm

Self-modifying code is seen as a big no-no nowadays, with modern processors having cache, execution protection and microcontroller having lots of ROM.

But back in the days, it was actually necessary. If you didn't have a stack, you had to store your own return address into a jump instruction; and if you didn't have an index register, you had little choice save to modify an instruction to point to a different address. Hell, some instruction sets even had specific instructions to write just the operand field of another instruction without changing the opcode .....

I've got a little bit of code which is already doing "naughty" direct accesses to framebuffer RAM, but it's really suffering from having only one Y register -- and leaving the poor X register feeling all unloved and helpless as Y gets shunted back and forth through zero page!

But if I wrote an address straight into a long,X instruction before I called my subroutine instead of writing it to a zero page pointer, X could be doing something useful, and I could save clock ticks and zero page space too. (Using (zp,X) would necessitate modifying the base address in-place, and so end up taking longer than carefully stashing Y.)

There really is not much not to like, apart from all the dire warnings about the world ending -- cats marrying dogs, horses with two heads and eight legs, plagues of frogs -- if the code that gets executed is not exactly the same as the code the programmer originally wrote. Worse than GOTO in the 1980s?!

So would anything really terrible happen if I used this technique on a Beeb? Do I really risk unleashing the forces of chaos with a careful STA into an address in my code? After all, we have stacks, index registers and indirect addressing modes for a reason. It's just that that reason, quite self-evidently, isn't "to keep your game actors from flickering horribly whenever there are several of them moving about on the screen" .....

I mean, it's hardly the world's most egregious sin, but I just see a flash of lightning and hear a crash of thunder every time I think about it!

User avatar
BigEd
Posts: 3461
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Self Modifying Code

Post by BigEd » Tue Jul 07, 2020 9:00 pm

Oh, go for it! The only arguments against (that I can think of) is that's it's harder to maintain and debug. But as you say, sometimes it's a big win for speed.

dp11
Posts: 1199
Joined: Sun Aug 12, 2012 9:47 pm
Contact:

Re: Self Modifying Code

Post by dp11 » Tue Jul 07, 2020 9:02 pm

Go for it . The only risk is you might break some emulation, but if you do the emulator needs to be fixed as self modifying code is was used in the 80's . Also *LOAD machinecode 3000 is a simple case of self modifying code. For some cases for real speed I've seen self modifying code in zero page.

User avatar
tricky
Posts: 4694
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Self Modifying Code

Post by tricky » Tue Jul 07, 2020 9:43 pm

I think Scramble has self modifying code that then runs to modify some other code and my beeb hasn't been sucked into a black hole yet.

PS The scrolling actually scrolls the code that draws the landscape, not the screen data.

VectorEyes
Posts: 378
Joined: Fri Apr 13, 2018 2:48 pm
Contact:

Re: Self Modifying Code

Post by VectorEyes » Tue Jul 07, 2020 10:13 pm

Personally, I use SMC all over the place where it will save space or cycles! But only if I *need* to save the space or the cycles!

User avatar
FourthStone
Posts: 1030
Joined: Thu Nov 17, 2016 2:29 am
Location: Brisbane, Australia
Contact:

Re: Self Modifying Code

Post by FourthStone » Wed Jul 08, 2020 12:53 am

I've seen it used (by me, borrowed from others) quite a lot for retrieving variable sized sprite data in a look up table and for plotting screen data.

With today's PCs having virtually unlimited ram and linear vram layout there's really not much to be gained by saving a few cycles, but on the beeb every cycle counts so it makes sense to optimise the code where ever possible.

User avatar
sweh
Posts: 2265
Joined: Sat Mar 10, 2012 12:05 pm
Location: New York, New York
Contact:

Re: Self Modifying Code

Post by sweh » Wed Jul 08, 2020 2:43 am

BITD, self modifying code was also used for copy protection.

Thinking back, the routine used a timer to generate a consistent sequence of bytes that were EOR'd against the loaded code. Once the decoding was complete they just jumped to the main entry point.

Of course if you single-stepped through the code (eg with EXMON) then you got the wrong sequence and ended up with garbage.

But like with most protection back then, once you saw the trick you could set a break point just before the jump, run the code at full speed and then save the resulting decoded data :-)
Rgds
Stephen

User avatar
Richard Russell
Posts: 1668
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Self Modifying Code

Post by Richard Russell » Wed Jul 08, 2020 9:51 am

julie_m wrote:
Tue Jul 07, 2020 8:40 pm
Self-modifying code is seen as a big no-no nowadays, with modern processors having cache, execution protection and microcontroller having lots of ROM.
Discouraged, certainly, but modern x86 CPUs retain the necessary functionality to ensure SMC works correctly (if slowly). Typically any attempt to write to 'code' memory will cause that page of the instruction cache to be flushed and re-fetched; obviously this can cause a major stall but it ensures that old self-modifying code will still work.

User avatar
sweh
Posts: 2265
Joined: Sat Mar 10, 2012 12:05 pm
Location: New York, New York
Contact:

Re: Self Modifying Code

Post by sweh » Wed Jul 08, 2020 5:40 pm

Some OS's or loaders may also block it eg by marking any writeable page as non-executable and marking all executable pages as read-only.

So even if the hardware can handle it, the execution environment might make it very difficult :-)
Rgds
Stephen

julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Self Modifying Code

Post by julie_m » Wed Jul 08, 2020 9:50 pm

Well, I've tried it, and it works! My computer did not go on fire or anything. It just draws on the screen, and does it very fast.

Unfortunately, I seem somehow to have reproduced a bug from my earlier, slower (?) version. But debugging is the fun of programming, isn't it?

julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Self Modifying Code

Post by julie_m » Thu Jul 09, 2020 1:15 am

Ah, I think I've properly got the hang of this now! The new code more or less just dropped over the old, apart from taking one of its parameters in a different address pair and using zero page entirely differently since I managed to eliminate a bunch of temporary variables!

I even spotted a place where I got to it by falling through from a BCC that did not branch, meaning the carry would definitely be set; so I just used ADC #&3F instead of CLC ; ADC #&40 like somebody who pegs their socks in pairs. I mean if you're going to get hanged for taking a lamb, you might as well get hanged for the biggest sheep you can find instead .....

Using BeebAsm means I can be extra-generous with comments, so I don't think there will be too many nightmares as a result of this foray into the dark side .....

VectorEyes
Posts: 378
Joined: Fri Apr 13, 2018 2:48 pm
Contact:

Re: Self Modifying Code

Post by VectorEyes » Thu Jul 09, 2020 1:29 am

julie_m wrote:
Thu Jul 09, 2020 1:15 am
I even spotted a place where I got to it by falling through from a BCC that did not branch, meaning the carry would definitely be set; so I just used ADC #&3F instead of CLC ; ADC #&40 like somebody who pegs their socks in pairs. I mean if you're going to get hanged for taking a lamb, you might as well get hanged for the biggest sheep you can find instead .....
It was exactly this that saved me the two cycles needed to fit a loop into 128 cycles, necessary for one of the effects in Evil Influences! Very satisfying it was too. Welcome to the dark side... ;)

julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Self Modifying Code

Post by julie_m » Thu Jul 09, 2020 9:45 pm

VectorEyes wrote:
Thu Jul 09, 2020 1:29 am
Welcome to the dark side... ;)
Thanks -- I think I might like it over here 8)

I've posted my effort so far in another thread here. Probably best to stick to that thread for discussing the specific application (direct manipulation of screen memory in a time-critical fashion) and keep this thread for discussing self-modifying techniques in general.

EDIT: I got burned! After all that care I had taken over the state of the carry flag, I instinctively used a defensive programming technique; which promptly broke in a way I should have spotted, but didn't until I tried copying 256 bytes of data.

No good wearing pit boots, where you really need to feel every blade of grass beneath your feet .....

Post Reply

Return to “programming”