Depends how you define it... D/d=[q,r]
(Dividend / divisor = [quotient, remainder])
- 5/2 = [2,1] (you have this one)
- -5/-2 = [3, 1] or [2, -1] (x86 way)
- 5/-2 = [-2, 1] (x86) or [-3, -1]
- -5/2 = [-3,1] or [-2, -1] (x86)
(On x86 CPU the sign of remainder r
is always the same as sign of dividend D
)
If you will take a look on the results above, in each case the absolute values are the same:
Remainder has the sign of the dividend, quotient has the sign of the dividend XOR divisor ([+, +] == [-, -] ==
+ vs [+, -] == [-, +] ==
-).
So you can add at the start of your routine a preparation part, which will test each value, and mark into some flag whether it was positive or negative, converting it to positive, do your division, then at current END
patch the results by the flags.
Something like (this is my first time ever with Marie Assembly, so take it more like a hint, and correct it where needed, hopefully only syntax, but maybe even logic errors may be there, I did not verify the code works!):
CLEAR
/ init temporary/result variables to zero
STORE q_flag
STORE r_flag
STORE RESULT
SUBT X / try (-Dividend) value
SKIPCOND 800
JUMP DividendWasPositive / positive or zero
STORE X / (-Dividend) positive, rewrite original X
STORE q_flag / set flags to positive value (X)
STORE r_flag
DividendWasPositive,
CLEAR
SUBT Y / try (-divisor) value
SKIPCOND 400
JUMP DivisorNotZero
HALT / division by zero detected, error
DivisorNotZero,
SKIPCOND 800
JUMP DivisorWasPositive
STORE Y / (-divisor) positive, rewrite original Y
/ flip quotient flag value (zero <-> nonzero) ("nonzero" == X)
LOAD X / will not "flip" anything when 0 == X
SUBT q_flag / but then q = 0, so it's harmless deficiency
STORE q_flag / q_flag is now zero or positive (X) value
DivisorWasPositive,
/ here X and Y contain absolute value of input numbers
/ q_flag is positive value when quotient has to be negated
/ r_flag is positive value when remainder has to be negated
/ .. do your division here ..
/ patching results by the q/r flags from the prologue part
AdjustQuotientSign,
LOAD q_flag
SKIPCOND 800
JUMP AdjustRemainderSign
CLEAR
SUBT RESULT
STORE RESULT / quotient = -quotient
AdjustRemainderSign,
LOAD r_flag
SKIPCOND 800
JUMP SignsAdjusted
CLEAR
SUBT REMAIN
STORE REMAIN / remainder = -remainder
SignsAdjusted,
HALT
q_flag, DEC 0
r_flag, DEC 0
... rest of your variables
Other option may be to have separate variants of routine for each situation (4 variants), as they will differ only in ADD/SUBT Y/ONE and the terminating condition 000 vs 800, which would execute fewer instructions for each case (better performance), but there would be a bit more code lines plus the code above may give you some new ideas, how to do things in Assembly.