Hello, i need to know how to use modulo in assembly. I need to be able to see if the number is a odd number or a even number. It would be nice if a could get an example of that too :)
Quote from: Farmek on April 12, 2013, 06:33:11 AMI need to be able to see if the number is a odd number or a even number.
assuming integers, you need only to test the least significant bit:
mov eax,value
test eax,1
jz @even
jnz @odd
;---
;MASM's HLL construct:
.if value & 1
; odd
.else
; even
.endif
Hi Farmek,
first things first: Welcome to the forum.
I think qWord gave the right answer. Another way is to use the normal division. From the Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-L, p. 278:
Quote
Operand Size Dividend Divisor Quotient Remainder Maximum Quotient
Quadword/doubleword EDX:EAX r/m32 EAX EDX 232 − 1
Gunther
Quote from: Farmek on April 12, 2013, 06:33:11 AM
Hello, i need to know how to use modulo in assembly. I need to be able to see if the number is a odd number or a even number. It would be nice if a could get an example of that too :)
Hi,
qWord showed the normal way to do it. If I take your
statement literally, then you would test a number for odd or
even by dividing by two, and checking for a remainder. The
remainder is the number modulo the divisor. That is more
work though.
OddNum DD 4321
EvenNum DD 1234
Two DD 2
MOV EDX,0
MOV EAX,[OddNum] ; Or EvenNum...
DIV [Two]
TEST EDX,0FFFFH ; Or 1 will work just as well.
JNZ ODD
; Else even.
HTH,
Steve N.
the DIV instruction is often said to calculate a "quotient" and a "remainder" from a "dividend" and a "divisor"
in fact, it calculates a "quotient" (sometimes called a "partial quotient") and a "modulus"
the actual "remainder" would be the modulus divided by the divisor
dividend/divisor = quotient = partial quotient + remainder = partial quotient + modulus/divisor
one interesting use of a modulus function might be to calculate the day of the week :P
Old Topic, but how to implement a modulo in MMX and SSE ?
Say, how to compute modulo 2 of something ?
Ex:
((x/2^n) mod 2) as described here: https://en.wikipedia.org/wiki/Bitwise_operation
Quote from: Farmek on April 12, 2013, 06:33:11 AM
Hello, i need to know how to use modulo in assembly. I need to be able to see if the number is a odd number or a even number. It would be nice if a could get an example of that too :)
Welcome to this forum Farmek.
qWord's answer to your odd/even question (testing the least significant bit) is the most used and fastest way to do it
without destroying any data. If the number to be tested would be of no further value (or its half value could be used), another option would be:
mov eax,value
shr eax,1 ;transfers the least significant bit to the CARRY flag
;and leaves the half value in eax
jc odd
jnc even
odd:
...
even:
...
The "modulo" is not as straight forward. Its meaning in most (if not all) programming languages is the residue of dividing an integer by another integer. For example, dividing 20 by 11 would give a quotient of 1 and a remainder of 9; thus, 20 mod 11 = 9.
The problem with HLLs is that the compiler never considers how much larger the original number may be compared to the modulus, and would automatically generate code to perform a division whenever the programmer calls for a mod operation. Unfortunately, the programmer himself may never consider any other option!!
As you can see with the above example, the same answer could be obtained using a simple subtraction. If you only have one of those to do, the timing required to perform the operation would not matter. However, if you have billions of them to do in a loop, it could matter.
According to available data, a division instruction would require
40 clock cycles while a compare or subtraction instruction only needs 1 clock cycle (if no fetching of data from memory is required).
But, if you don't know the extent of the number to be "mod'ed", you don't really have any option but to perform a division (much faster than 100's or more subtractions). And, here again, several precautions need to be taken in assembly to prevent your algo from crashing when coding a division. If you are not familiar with the requirements of assembly instructions, I would recommend reading instructional material.
As a side note, I recently came across a problem where integers resulting from the sum of at most three integers already lower than the modulus needed to be processed. Using subtractions, I could run a loop containing three of those operations 500,000,000 times in about 10 seconds on my old desktop.
If the divisor is a multiple of 2 (4,8,16,32,64,...), masks can be used:
and reg,1 ;(1h)
jz even
odd:
You are looking for the rightmost bit whether zero or one if dividing by 2.
If it's the remainder of the division by 4, then the mask will be:
and reg,11b ;(3h)
;reg = remainder of number divided by 4
remainder of the division by 8 the mask will be 111b ;(7h)
remainder of the division by 16 the mask will be 1111b ;(15h)
Usually the mask is a multiple of 2 minus 1, if and only if the divisor is a multiple of 2.