News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

modulo

Started by Farmek, April 12, 2013, 06:33:11 AM

Previous topic - Next topic

Farmek

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 :)

qWord

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
MREAL macros - when you need floating point arithmetic while assembling!

Gunther

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
You have to know the facts before you can distort them.

FORTRANS

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.

dedndave

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

guga

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
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

raymond

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.

Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

mineiro

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.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything