[Scummvm-devel] Decompiler survey: Variable stack effects
Torbjörn Andersson
eriktorbjorn at telia.com
Wed Jun 16 07:53:43 CEST 2010
On 2010-06-12 14:47, Michael Madsen wrote:
>However, some opcodes, like startScript in SCUMMv6, take a
> list of arguments from the stack. That requires us to know something
about the
> stack in order to determine the effect - just knowing the opcode is
not enough.
>
> Ideally, this should be determinable during disassembly simply by looking at
> the previous instructions in the bytecode, but this cannot necessarily be
> guaranteed: in theory, it is possible to fill the stack with the
arguments and
> then perform a jump to the special opcode. Another problem might
occur if the
> information used to determine the size of the argument list isn't
pushed as a
> constant, but taken from a variable.
>
> This brings me to my questions:
> 1) Does your engine have any opcodes that act in a similar way?
> 2) If yes, do you know if this sort of thing is actually used in any scripts
> for your engine?
If I understand the question correctly, and I'm not mistaken, it
shouldn't be a problem for the Broken Sword 2 engine. The stack is a
local variable in runScript2(). When an opcode function is called, it
pops the desired number of parameters into an array and passes that
array to the opcode function, so they themselves know nothing about the
stack.
There is a rather primitive disassembler, "desword2", in the ScummVM
tools package. Here's what the output can look like for a short script:
0000: SAVE_MCODE_START
0001: PUSH 0
0006: PUSH &local(0)
0009: PUSH &local(20)
000c: CALL 3, fnRegisterFrame
0010: SAVE_MCODE_START
0011: PUSH &local(20)
0014: CALL 1, fnUpdatePlayerStats
0018: END
Crude, but it has been occasionally useful for finding script bugs even
if I've always had to rewrite its output manually into something more
readable.
I'll admit that I don't know exactly what all it can print means, but I
believe that every function call starts with a "SAVE_MCODE_START"
instruction, because depending on what the opcode function returns it
may decide to call it again. (E.g. for opcodes that wait for a condition
to become true.) It then pushes a number of parameters onto the stack,
and finally calls the function. The number of parameters and the
function to call are part of the call opcode, and as far as I know
there's no such thing as a self-modifying script.
Torbjörn Andersson
More information about the Scummvm-devel
mailing list