[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