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 atoi
push 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_1101b
bt al, 0 ; copies the bit to the Carry Flag
jc 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,00
MOV 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,0000
MOV BH,00
MOV BL,02
DIV BX
CMP 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 one
BNE Odd ; zero flag not set - meaning it's odd
MOV 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 accumulator
detect_even:
substract 2 from accumulator
skip if accumulator is positive
goto zero_or_neg
# 'accumulator is positive'
goto detect_even
zero_or_neg:
# accumulator is -1 or 0
skip if accumulator is zero
goto not_even
# 'accumulator is zero'
# no op, goto even, or omitted instruction
even:
# 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 Done

WasOdd: ...

Done: stop

Orig: .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,101b
test 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


Related Topics



Leave a reply



Submit