I want to check if the value of the register ax is divisible by 7, with remainder = 0. How can I do it?
Asked
Active
Viewed 3,617 times
0
-
1Should the value in AX be treated as signed or unsigned? Are you limited to 16-bit mode, and if so, why? Will an answer using IDIV be acceptable, or are you looking for a clever trick that avoids the (slow) hardware divide instruction? Why are you writing assembly language by hand in the first place? – zwol Oct 15 '16 at 18:26
2 Answers
7
You can use the same way as shown in this answer, with different constants of course.
The modular multiplicative inverse of 7 mod 216 is 0x6db7, which (by definition) means that numbers of the form x = n * 7 will obey x * 0x6db7 = n, where n will be less than or equal to 0xffff / 7. So if you get something bigger out of x * 0x6db7, you know it's not a multiple of 7. Also, non-multiples of 7 cannot also map to low results, because multiplication by an odd number modulo a power of two is bijective.
So you can use (not tested)
imul ax, ax, 0x6db7
cmp ax, 0x2492
ja not_multiple_of_7
This is for unsigned numbers of course.
As a bonus, ax will be the original value divided by 7 iff it was a multiple of 7.
-
If you have a CPU with multiply (e.g., Intel as you are showing) there is also typically a divide instruction which will produce a remainder; divide and check the remainder. That's conceptually simpler. Your scheme is good when the *performance* of this check matters; if it does then this scheme should be used (and marked with appropriate comments) In most circumstances, performance won't matter, and this bit of magic will be opaque to most readers, producing code which is difficult to maintain because it depends on mathematics most readers don't have. (Upvoting because it is clever). – Ira Baxter Oct 15 '16 at 19:10
-
@IraBaxter: I thought the "without remainder" phrase in the question meant "without *using* a remainder instruction". But the OP's self-answer proves that's not what was meant. – Peter Cordes Oct 15 '16 at 22:13
1
org 100h
mov ax,14
mov cl,7
div cl
cmp ah,0
je positive
PRINTN "The number has a remainder"
jmp finish
positive:
PRINTN "The number has no remainder"
finish:
PRINTN "After comparison"
mov ah, 0
int 16h
ret
liadperetz
- 87
- 3
- 11
-
2Ok but be careful with this, it relies on the quotient being 255 or less, 1792 and up will cause a #DE – harold Oct 15 '16 at 19:10