[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [LONG, off-topic]] Interactive Programming




>      In any event,
>      I was impressed enough that I quit looking for the
>      offending test,
>      telling the Big Boss I couldn't find it.
>      He didn't seem surprised.

Reminds me of a time, years ago, where I was trying to modify a program
written in 6502 assembler.

In addition to pervasive self-modifing code, another extremely popular
practice of the era was inlined function-call parameters.

Unlike the C approach, which most of you are probably familiar with, where
parameters are pushed onto the stack, then a subroutine is called which
pops them, instead the subroutine would pop the return address, and use it
as a pointer to the function parameters.  At the end of the function, the
return address pointer would be incremented and jumped to.

You're probably thinking, this is nuts.  Why would anyone do this?
Consider the following line of C code:

  result = function(x,y,z);

One could write this in 6502 assembler as:

  JSR function
  DATA x
  DATA y
  DATA z
  STA result

where x,y,z,result are pointers to storage locations.  This made coding
in assembler just as easy as coding in C, and it took less memory because
you didn't need all those push/pop instructions.  Doing this on a modern
processor would probably wreck havok on the decode pipeline.

Apple's ProDOS used this type of calling sequence, and most disassemblers
dealt with this special case by correctly identifying the parameters as
such.  But one of the worst I ran into was this:

  JSR printf
  ASC "Hello, world!",0
  ...

You can imagine what the disassembler did with that.  Spit out all sorts
of garbage as it tried to interpret the ASCII string "Hello, world!" as
machine instructions.

I encountered this in some BBS software, and had a real difficult time
reading it.  Finally I got the idea of taking the partially disassembled
code, identifying all the branch target addresses, then redisassembling
starting at those addresses.

It worked.  After a few iterations of this I had all the entry points, and
everything that didn't disassemble cleanly was outputted as hex data.

For fun, run objdump on a cleanly compiled unix binary... It makes it all
look so easy... :)