I’ve been delving further into the subject of self-modifying programs on the TinyELF. Take the program that I showed you in the last posting on the subject for instance:
0000 3F BN4 Wait for you to press I
0001 00 3F branches to THIS address if you don’t press “I”, if you do press “I”, it skips to the next address
0002 6c INP 4 Take whatever is in the IN 4 buffer and put it into the next location in memory, then executes it
0003 00 IDL It actually doesn’t matter WHAT you put in this spot since the 6C command will change it anyways
0004 00 IDL after it 6C changes the previous bit, stop (or not depending on what input you send to the program)
Key in the program and then run it. Type in 6C and then “I”. So the program fills the memory ENTIRELY with 6C commands. This is because 6C takes anything sitting in the “In 4” buffer and sticks it in the next byte but that’s not all. It also RUNS IT! So when you put in 6C, it still sees 6C in the buffer and then replaces the next byte and then runs that byte which is now 6C, rinse and repeat many, many times.
Now that the memory is filled entirely with 6C’s, re-key the first part of the program:
0000 3F BN4 Wait for you to press I
0001 00 3F branches to THIS address if you don’t press “I”, if you do press “I”, it skips to the next address
0002 6c INP 4 Take whatever is in the IN 4 buffer and put it into the next location in memory
Now type in something like C4 and hit “I”. If you remember from my last post, C4 is a “no op” command which just tells the computer to skip that byte. I’ll let you run this yourself to see the output but it’s rather interesting. See if you can guess what will happen by logical reasoning.
So far, the only command I find that overwrites the program itself is when you enter 6C. There may be other ways but I’m not an assembly language ninja quite yet.
If you like the content on this site, please support it by using this link to order from Amazon. You know you were going to go there and buy stuff anyhow so why not help me pay the hosting bill.
Having seen your tweet about TinyELF, I thought I’d drop by and see how it was going. Seems like you’re getting a lot out of Tom Pittman’s “Short Course,” and I’m grateful that Tom let me share that through both the website and TinyELF’s own built-in help. It’s the book I first learned assembly language basics from 30 years ago. TinyELF is, in a sense, an homage to Tom and others who laid the foundations of my own career.
The INP (input) instruction must seem very strange at this point, but it’ll make a lot more sense after you tackle the register operations in chapter 4. One of the fun things about the “Short Course” is that it doesn’t tell you everything you need to know before digging in and using an instruction. The result is a lot of “Aha!” moments, when the missing puzzle piece drops into place.
If you run into any snags, feel free to drop an email, or hit up the folks on the Yahoo group ( http://groups.yahoo.com/group/cosmacelf/ ). There are a surprising number of people who still have an interest in this old microprocessor.
Tom’s book has been an excellent resource. I’ve come to find that assembly language IS a confusing subject however. The part that makes it confusing is all of the side-effects that you have to consider. For instance, when you run an instruction, R0 increments by default unless P is pointed somewhere else and everything you move seems to have to pass through the accumulator. I still don’t understand “I” and “N” yet. I think I need to go back and spend more time with step mode. Also 6C is just downright dangerous I’ve noticed. Especially if you LIKE that program you’ve been working so hard on. I’m well into chapter 4 now. I thought I understood registers until I cracked open chapter 4… lol. I just joined the Yahoo group on your suggestion.
The I and N registers are dead simple. Take the SEQ instruction, hex 7B. The I register contains the high four bits of an instruction opcode, the N register contains the low four bits, so for SEQ I=7 and N=B. That’s all there is to I and N.
For some instructions it makes sense to talk about the high four bits and low four bits separately. Take an instruction like INC 7, encoded in hex as 17. The I (instruction) register is 1, indicating an increment instruction, and the N register is 7, the number of the register that will be incremented. This allows documentation to say that the increment instruction increments the register specified by N, but in practical terms that just means the register specified in the low four bits of the instruction.
To verify this in TinyELF, open the Trace and 1802 State panels and single step through a program. You’ll see each opcode in the Trace panel split up into the I and N registers in the 1802 State panel.
You’re right, the 1802 does pass nearly everything through its accumulator. Other microprocessors offer different instruction sets where the accumulator isn’t used so heavily. The 1802 is both a bit elegant and a bit odd, but still makes for a good introduction machine language programming.