Can you write to [PC]?
Asked Answered
Q

2

7

According to the DCPU specification, the only time a SET instruction fails is if the a value is a literal.

So would the following work?

SET [PC],0x1000

A more useful version would be setting an offset of PC, so a rather strange infinite loop would be:

SET [PC+0x2],0x89C3 ; = SUB PC,0x2
Queenqueena answered 5/4, 2012 at 15:13 Comment(4)
What is "DCPU specification"? Please provide a link if you have one.Reasoned
@AaronDigulla, 0x10c.com/doc/dcpu-16.txtQueenqueena
+1 Oh how I love imaginary computing :)Loquat
@AustinHenley: It's only imaginary until 0x10^c is released ;)Repeal
R
7

Probably (= I think it should work but I didn't try).

This is called "self modifying" code and was quite common the 8bit era because of a) limited RAM and b) limited code size. Code like that is very powerful but error prone. If your code base grows, this can quickly become a maintenance nightmare.

Famous use cases:

  1. Windows 95 used code like this to build graphics rendering code on the stack.
  2. Viruses and trojans use this as an attack vector (write code on the stack or manipulate return addresses to simluate a JMP)
  3. Simulate switch statements on the C64
Reasoned answered 5/4, 2012 at 15:32 Comment(9)
The only difference that I can see is that you can't execute code on the stack with DCPU, since PC values are in a completely different memory space to the stack/ram, so SET PC,### cannot be made to jump onto the stack.Queenqueena
@Mat - You can execute code on the stack with DCPU. Take a look at the very bottom of the DCPU specification. The memory dump of that code.Mismatch
@kisplit, You can put code on the stack, but how do you jump to it? That dump is just the executable code.Queenqueena
@Mat - SET PC, 0xFFEF. And say I want to jump to the start of my program again: SET PC, 0. Now say I have instructions that write data to 0x1000-0x10F0. I can execute that too with: SET PC, 0x1000Mismatch
So you are saying that the code is stored in the ram? I know how to jump, but my understanding of DCPU is that the two are in different memory spacesQueenqueena
@Mat SP starts with a value of 0xFFFF, as written in the spec: By using 0x18, 0x19, 0x1a as POP, PEEK and PUSH, there's a reverse stack starting at memory location 0xffffZarzuela
@kisplit, Ok. That's the main thing I was trying to get my head around. As an assembly programmer, I'm used to having sections, which can be labeled as read-only.Queenqueena
@Mat - Heh, on windows and linux it's easy to turn those pages as writable. VirtualProtectEx comes to mindMismatch
@KevinCoffey minor nit, but SP actually starts at 0x0000, it's just a PUSH decrements SP before writing to [SP] so it's 0xFFFF at the time of first write.Permenter
B
4

There's no value for [PC], so I'm guessing you need to do it in a round-about way by storing PC in something you can use as a pointer (registry or memory).

        SET  A , PC
        SET [A+3], 0x8dc3 ; SUB PC, 3 (if A can't be changed from outside SUB PC,2 works too.)
Brittabrittain answered 5/4, 2012 at 17:24 Comment(2)
That code wouldn't work, as the code section uses the same numbers as the ram/stack. A after that statement would evaluate to a number, and then [A+3] would refer to that position in memory, rather than in the code section.Queenqueena
@Mat - There are no separate sections. You can write self modifying code with DCPU.Mismatch

© 2022 - 2024 — McMap. All rights reserved.