"tweetable" "symbolic" hex COM loader
dave.long at bluewin.ch
Thu May 24 17:36:10 EDT 2012
> I didn't previously note this, but this nop suggests that this code
> was not
> written with an assembler. nop-padding allows you to expand and
> shrink code
> sections without recalculating addresses.
This is why I'm currently extremely biased towards straight-line code
at the expense of program size: I've allowed myself an editor, but
not an assembler. Knuth claims that a single-pass bootstrapping
assembler such as MIXAL should be an afternoon project; I hope
that he's referring to the time he took for his sixth and not for his
(just checked some hand assembly: did 36 instructions in 27 minutes,
about 46 s/instruction to assemble and 75 s/address for the
relocations. That would say I should be willing to use many more
jumps, except that the mistakes I made during the hand assembly were:
(1x) wrong opcode due to poor handwriting, (2x) registers switched in
mov r,r, and (1x) my jump offset was completely bogus; the first two
sorts of mistakes I normally minimize by heavily copy-pasting working
code segments, but the offsets must be recalculated every time --at
least, as you noted, modulo the nop-padding!-- something changes in
> Whew. That's pretty tricky. At the end, %dx is mem[label + 0x200]
> - (0x101 +
> %cx). The last part is presumably the address where we're currently
> assembling, and the first part is the value of the referenced label.
> I wonder if there's a simpler way to write the above.
There is indeed. Current code uses XLATB (just after setting ' ' to
dot) and is therefore down to the minimal single backwards branch per
> This is presumably a very clever way to convert hexadecimal digits
> into a
> binary nibble. I've never learned enough about AAM and AAD to make
> use of
Posted it a while ago on kragen-discuss, this relies on linear
algebra that isn't apparently implemented in some recent non-intel
HW, but should have worked "in period".
> Which is where int 21h function 02h writes it to stdout from. The
> list I found warns that %dl=0x09 will get converted to some 0x20s,
> but that
> can't be right, or this program would fail to assemble itself.
That is indeed correct: I just retried self-reassembly and indeed
have 0x20's here (along with an easily observed incorrect
executable!), which should teach me something about sending mail
after roughly eyeballing the output to see that the fixups came out
instead of testing (or even just dd'ing the disk sector back to unix
A workaround should simply be to "sub dl,0x99" at the very end
instead of for each nybble, but because:
- there's also some bx-relative addressing that runs afoul of this, and
- i'm suffering intermittent disk corruption (which, however much it
adds to the versimilitude, isn't very enjoyable)
I think I'll switch to C-like writes instead for the time being
(although they probably weren't around in 1.0 either)
Maybe a real dosbox would help, as your octalinput.com also redirects
the typescript to the output file under my setup.
> My temptation to write a one-pass stack-based octal version is even
> greater now
> :). It probably can't be under 40 bytes, but maybe it could be
> under 70. And
> it could be used to write the above.
Under 70 sounds plausible.
I'm currently taking:
76 - straight octal input (about half of which is various cargo-
culted int 21's)
96 - one-pass; labels only good after definition
111- two-pass; labels also good for forward branches
(add 2 bytes to each to decode hex instead of octal)
So I'd bet you'll easily have it in roughly 40+20 = 60 bytes.
Knuth, Structured Programming with go to Statements, Computing
Surveys, Dec 1974
> ... MIXAL is a good example of a "quick and dirty assembler", a
> genre of software which will always be useful in its proper role.
> Such an assembler is characterized by language restrictions that
> make simple one-pass assembly possible, and it has several
> noteworthy advantages when we are first preparing programs for a
> new machine: a) it is a great improvement over numeric machine
> code; b) its rules are easy to state; and c) it can be implemented
> in an afternoon or so, thus getting an efficient assembler working
> quickly on what may be very primitive equipment. So far I have
> implemented six such assemblers ...
More information about the Kragen-discuss