On 6 May 2017 08:09 -0700, from corey(a)lod.com (Corey
Lindsly):
Anyway, I reached one point in the assembly code
that I simply could not
understand. It seemed like a mistake, and I went through it again and
again until I finally realized what it was doing. There was a branch/loop
that jumped to the middle of a multi-byte machine instruction, so that
branch had to be disassembled and stepped separately until it "synced" up
with the other branch again. Maybe this is standard practice in
programming (I don't know) but at the time I thought, what kind of evil
genius devised this to save a few bytes of memory?
IIRC, that _was_ a common trick at least on machines of that class. It
did have the potential to save a few bytes, yes (more if the
instructions were such that you'd get some _other, desired_, behavior
by jumping into the middle of one with some specific state), but it
also foiled lots of disassemblers: Simply disassembling a binary from
start to finish would yield nonsense in those locations, as you
experienced. It thus basically forced you to single-step those
instructions to figure out what was going on from the binary.
I'm pretty sure it works on every architecture with variable-length
instructions and arbitrary jump capability, as long as you have
control over the specific machine instructions generated (such as if
you are programming in assembler). Of course, it _is_ also a total
nightmare to maintain such code.
I would absolutely not say that doing something like that is standard
practice in modern programming. Even in microcontrollers, where
program and data memory can be scarce even today, I would argue that
the costs would not outweigh the benefits by a long shot.
In 6502 code, it's not uncommon to do something like
foo1: lda #$00
.byte $2C ; 3-byte BIT
foo2: lda #$01
.
.
.
to save a byte (and probably still done for the few who write in ASM).
The "2C" operand would cause it to disassemble as something like...
1000- LDA #$00
1002- BIT $01A9
which is the route you'd go down if you called "foo1". Apart diddling a
few CPU flags, and an unneeded read on $01A9, harmless.
(Most 6502 programmers would probably see a strange BIT instruction as an
attempt to do this.)
It's probably not a good idea to still do this unless you're really REALLY
crunched for space.
-uso.