Hello clf,
I have about a week's worth of spare-time learning of ARM assembly under my
belt. You can see some of the fruits of that at
http://minimaltype.com/13.txt
http://minimaltype.com/innerloops.txt
(13 preceded by 1.S, 2.S, 3.S, and so on, starting from hello world.)
Once I got to the level of 13.S, I started converting AvdH's yourforth from x86
to ARM. For the most part, despite my knowing almost nothing at all about x86
assembler, this has been a real pleasure. ARM assembler is really a joy to
work with, or at least I think so now after bashing my head against a few walls
early on. Especially ARM's stack words and conditional instructions are very
clean and flexible. The conversion to ARM assembly was also proceeding at a
pretty quick pace... until I hit the first word requiring division.
Which brings me to the subject of this post.
I can perform division with repeated subtraction (using subtract-with-carry to
divide a 64-bit dividend by a 32-bit divisor), but what do I do about negative
numbers? My education takes me as a far as, for ratios, "if they're both
negative, that cancels out - they are now both positive; if one is negative,
normalize the ratio so that only the numerator is negative; if the ratio is
reduced [i.e., if division is performed], the result has the sign of the
numerator." Which doesn't cover the sign of the remainder, which is apaprently
not the same thing as the modulus, which is apparently controversial.
Can someone clearly describe, or point me to a clear description, as to how one
*implements* floored division vs. symmetric division? Suppose I start out by
discarding signs and just repeatedly subtract numbers until I get a positive
quotient and remainder. What do i then do to satisfy callers expecting foored
or symmetric division? This has proven to be remarkably difficult to search
for. Wikipedia literally just says that things "break down" when negative
numbers are involved. yourforth just uses x86's idiv instruction. An ARM
jonesforth that I've found has a division routine, but out of excessive
unconcern for ANS compatibility it doesn't identify what kind of a routine it
is.
I'm aware that this manner of division is going to be dreadfully slow. For
known divisors I'll have a way to perform the division with multipication,
Otherwise this is fine for now.
And I feel compelled to add.. I'm not writing a Forth. I'm porting a Forth.
Starting with yourforth as it's small and commented well enough to make up for
my not knowing x86. I'm using gas as there's a convenient package of gcc for
Android, and as fasm doesn't seem to actually have arm binaries.
Thanks,
-- Julian