Re: Disassembly of Farbrausch's "fr-016: bytes"

Kragen Javier Sitaker <[email protected]>
Newsgroups gmane.culture.people.kragen.discuss
Message-ID <[email protected]>
Hi, haven't heard from you in a while!  How have you been?

On Thu, Nov 27, 2008 at 12:37:36AM +0100, Dave Long wrote:
> I was testing out a rudimentary python 16-bit x86 assembler with the  
> code from:
> 
> http://canonical.org/~kragen/demo/fr-016.html
> 
> and, although my source:
> 
> >org 100
> >mov ax,13
> >int 10
> >les bp,[bx]
> >
> >l loop
> >stosb
> >adc ax,di
> >adc ax,1132
> >jmp loop
> 
> 
> results in a slightly different 15 bytes:
> 
> 0000000: b813 00cd 10c4 2faa 11f8 1532 11eb f8    ....../....2...
> 
> I still get the same visual output in QEMU.

It *is* animated, I assume?  

Note that the 1132 in the original was 1132 decimal; it seems to have
become 3211 hex in your output program.

> I think the 1132 is an immediate, and the FS override is there (a) as  
> padding or (b) to potentially confuse disassemblers.

Well, the original instruction is 64 13 06 6c 04.  6c 04 is 0x46C, 1132
decimal.  Intel document 253666 p. 3-27 says that the "13" opcode is for
"ADC r16, r/m16" or the 32-bit equivalent; immediate adds use the opcode
bytes 14, 15, 80, 81, or 83.  (64 is the FS prefix, says p. 2-2.)  So I
don't think it's an immediate; I think it's a memory address.

QEMU seems to agree with me, in that twiddling the memory at address
FS:0x046C via GDB caused a change in behavior --- it wouldn't have if
QEMU interpreted the operand as an immediate.

It's definitely padding/obfuscation though.  MS-DOS machines don't have
memory-mapped I/O in any of the plausible places it could be reading
from, so reading the memory is side-effect-free; it could just as easily
have used `adc ax, $increment`, as your version does (using the opcode
byte 15), which would have been three bytes instead of five, and much
less mysterious.

My hypothesis is that ancient MS-DOS versions wouldn't have initialized
FS because they didn't know about it, so it would have remained at
whatever the processor initialized it to at startup, probably 0; FreeDOS
initializing it to the same as the other segment registers is an
incompatibility from the point of view of this program.

> dc -e '16i2o 1132p' yields 1000100110010, so it seems reasonable that  
> the second adc helps create a nice LFSR-like term.  But I don't  
> understand why your attempts at manually removing the FS override  
> wouldn't have given the same behavior that I see.

I think it's because of the 13 vs. 15 opcode difference.

Regards,
Kragen
-- 
To unsubscribe: http://lists.canonical.org/mailman/listinfo/kragen-discuss
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.