﻿ Finding Number Is Even/Odd in Assembly - ITCodar

# Finding Number Is Even/Odd in Assembly

## Finding number is Even/Odd in assembly

Your code does not work because when you ask the user for a number, you read in an ASCII encoded string. You will need to call `atoi` (ASCII to INT) first to convert the string to a "real" number as computers see it. `atoi` is included in glibc.

``extern atoipush eax ; pointer to your string to be converted, eg '123'call atoi; now eax contains your number, 123``

You can also do a bit test on the least significant bit (bit 0) to find out if it is even or odd:

``mov al, 01000_1101bbt al, 0 ; copies the bit to the Carry Flagjc its_odd ; jump if CF==1; else - it's even (CF==0)``

What BT does, it copies the bit to CF and you can do conditional jumps based on that.

## 8086 assembly language program to find number of odd and even numbers in an array of 16-bit hexadecimal numbers

This makes the output of the program `EOOOO` instead of `EOOOE`.

You seem not to be fully aware what the following instructions in your code actually do:

``MOV AX,00MOV AX,[SI+1]MOV [SI],AX``

The first instruction is useless because the second instruction will overwrite the value of `AX`.

Because your array consists of 16-bit values and x86 CPUs use byte-wise addressing (like most but not all CPUs), the second value will be stored at the address `[SI+2]`, not at `[SI+1]`.

By reading `[SI+1]`, you read some (non-sense) value which can be calculated from the first two numbers in the array.

And using the last instruction you overwrite the first number in the array, which makes no sense to me.

You never modify the `SI` register. Without modifying the `SI` register, you will never read values later in the array!

So what your program does is the following:

``   Initially, your array contains the values 100h,16Fh,...   You check the value 100h (if it is even or odd) MOV AX,[SI+1]   loads 6F01h into AX MOV [SI],AX     overwrites the first value in the array by 6F01h   You check the value 6F01h (if it is even or odd) MOV AX,[SI+1]   loads 6F6Fh into AX MOV [SI],AX     overwrites the first value in the array by 6F6Fh   You check the value 6F6Fh (if it is even or odd) MOV AX,[SI+1]   loads 6F6Fh into AX MOV [SI],AX     has no effect ...   ... because the first element of the array is already 6F6Fh MOV AX,[SI+1]   loads 6F6Fh into AX   ... MOV AX,[SI+1]   loads 6F6Fh into AX   ... MOV AX,[SI+1]   loads 6F6Fh into AX   ...``

So the first time your program checks if `100h` is even or odd. This is what you want.

The second time it checks if `6F01h` is even or odd. And the third, fourth, fifth ... tenth ... hundredth time, it checks if `6F6Fh` is even or odd. This is what you probably don't want.

In order to determine if the hexadecimal no is even, the program would divide the number by 2 and the remainder should be equal to zero.

If you work with decimal numbers (without a computer) and want to check if a number is divisible by ten - would you also divide the number by ten and look at the remainder?

No. You would look at the last digit and check if it is zero.

You can do this in all numeral systems:

In ternary system, a number is divisible by 3 if the last digit is zero; in hexadecimal system it is divisible by 16 if the last digit is zero. And in binary system it is divisible by two if the last digit (= bit) is zero.

You can use the `TEST` instruction to check if a bit is zero or one:

The instruction `TEST xxx, 1` checks if the last bit of the value `xxx` is 0 and set the zero flag if this is the case (and clear the zero flag otherwise). This means that the `JZ` instruction (which is the same as `JE`) will jump if that bit was zero. And `JNZ` (`JNE`) will jump if that bit was one.

So you can replace the following code by the instruction `TEST AX, 1`:

``MOV DX,0000MOV BH,00MOV BL,02DIV BXCMP DX,0``

And you can even use `TEST WORD [SI], 1` to directly check the bit in a number from the array, so you don't even need to use `MOV AX, [SI]` to load the value into the `AX` register.

## ARM Assembly Even or Odd Number in Register

Evenness of a number can be determined by its zeroth bit. Odd numbers have one, even numbers have zero.

In the ARM assembly, to perform a conditional, you do an arithmetic operation that affects flags. To check the value of a single bit, you either do an AND with 1, or do a TST with 1. The latter is AND with no destination - it performs the bitwise AND but throws away the result.
So, to recap:

``TST r4, #1 ; TST with 1, like AND with 1, will zero out all bits but the rightmost oneBNE Odd ; zero flag not set - meaning it's oddMOV R1, R4; Output... Do you know how?Odd:; Continue with the loop...``

## Is there a way to determine whether or not a number is even or odd using marie assembly language?

The original code is using a valid approach to solving the task. The pseudo-code below is constructed to show how one might use the limited skip-branching in MARIE. Using label names a comments can help to illustrate expectations at various statements.

``  load X into accumulatordetect_even:  substract 2 from accumulator  skip if accumulator is positive    goto zero_or_neg  # 'accumulator is positive'  goto detect_evenzero_or_neg:  # accumulator is -1 or 0  skip if accumulator is zero    goto not_even  # 'accumulator is zero'  # no op, goto even, or omitted instructioneven:  # here X is even as accumulator is 0  # use X, perhaps add to running total?not_even:``

Note that the accumulator is reused for the primary detection loop, much as though `X - Y - Y - Y - ..`. YMMV with negative numbers.

## Finding even or odd in assembly language

Wow, that's a very ... limited ... CPU :-) Without an `and` instruction, you may find it necessary to do a `divide` (by two) of the value, then a `multiply` (by two) of that result.

Assuming that `divide` is an integer operation, the half-value will be rounded or truncated if the original value was odd so, for example, both `4` and `5` halve to `2` then doubling that gives `4`.

The result of that half-then-double operation will therefore be identical to the original value if that value was even, otherwise it will differ.

So you could then use a `subtract` followed by a `jmpn` to choose an even or odd code path.

In other words, something like this:

``Start:   read                  // read to accumulator and store.         store    Orig         divide   Two          // round to even then subtract original.         multiply Two         subtract Orig         jmpn     WasOdd       // Choose even/odd code path.WasEven: ...         jump     DoneWasOdd:  ...Done:    stopOrig:    .data 2 0             // For original data.Two:     .data 2 2             // For halving/doubling.``

Keep in mind this is untested, but it's probably a good place to start. I'm particularly unsure of the `.data` pseudo-op but, based on sample code, the intent is to provide a size (byte count) and initial value. If I've misunderstood how it works, you'll need to adjust for that.

## AVR Assembler check is number odd

AVR allows efficiently testing any single bit by copying it into the T flag with `bst` where you can branch on it. (Or copy it to another bit of another register with `bld`, as shown in the manual's example for `bst`.)

The key instructions here:

• `BST` – Bit Store from Bit in Register to T Flag in SREG.
• `BRTC` – Branch if the T Flag is Cleared (There's a corresponding `BRTS` for T==1)
``   bst   r21, 0            ; T = (r21 >> 0) & 1   brtc  is_even           ; jump if (r21 & (1<<0) == 0)``

Or even better, if your branch only needs to skip one instruction, `sbrs` - Skip if Bit in Register is Set. (The skipped instruction could itself be a branch, if you wanted, but bst / brt[sc] may be faster in that case.)

``   sbrs r21, 0     nop              ; runs only for even R21   ... code that runs for both cases``

e.g. GCC uses it when compiling `if(x&1) bar();` (Godbolt):

``foo:        sbrs r24,0        ret             ; return (skipped for odd)        rjmp bar        ; else tailcall``

The manual says `tst reg` is just an alias for `and reg,reg` to set flags according to the whole value. (html extract).

Unlike some ISAs with more opcodes (like ARM where you would `tst r0, #1`), AVR doesn't have a non-destructive AND-but-only-set-flags instruction, only a `cmp` (which is like sub but doesn't modify the destination reg). If you wanted to do it that way, you could load a `1` into another register and AND into that, setting or clearing the Z flag for BRNE or BREQ.

Or `andi r21, 1` if you don't mind destroying r21. Or right-shift it to shift the low bit into the carry flag. This does still let you branch on odd/even in 2 instructions instead of 3, in a way that's more like other ISAs.

## how TEST instruction check if number is EVEN or ODD in assembly language

I think i understand it now, that how can test be used to find out if number is even or odd!!!

You just have to check the least significant bit of the number,

example:

1001 is odd,

1110 is even

I want to check if 101 is even or odd

then i'll do this:

``mov  al,101btest al,1b``

by doing this,

test will perform and operation between 101 and 001

so only the least bit would be checked and if it is '1' then number is odd otherwise even

then finally we can use jump to print if number is even or not:

``je ; if number is even``