arraysassemblybit-manipulationx86-16tasm

# how to check if 2 numbers have reversed bits in assembly?

My code should get 2 arr with the same length(k) and to check how much pairs of numbers have the same index (1 in arr 1 and the other in arr2) and are opposite, which means the first bit in 1 should be the last in the other and the second to first would be the second to first and go on...

Overall, this is my code:

``````IDEAL
MODEL small
STACK 100h
DATASEG

k dw 2                       ;length of arr1 and arr2
ARR1 dw 2 dup (?)
ARR2 dw 2 dup (?)
CODESEG
start:
mov ax,@data
mov ds,ax

lea si,[ARR1]
lea di,[ARR2]
mov cx,k                 ; cx=length of arr
xor dx,dx
mov [ARR1],1000000000000001b
mov [ARR2],1000000000000001b
mov [ARR1+1],0033h
mov [ARR2+1],0033h
xor dx,dx
L1:                                      ; loops through every index in both arr1, and arr2
mov bx,k
sub bx,cx
push cx
mov cx,16
L2:
xor ax,ax
shr [si+bx],1
jnc nc1
inc al
nc1:
clc
shl [di+bx],1
jnc nc2
inc ah
nc2:
clc
cmp al,ah
jne end_loop2

dec cx
jnz L2

inc dx
end_loop2:
pop cx

dec cx
jnz L1

exit:
mov ax, 4c00h
int 21h
END start
``````

My debugger doesn't give me any errors but when I run the code it doesn't work, when I shift left the number in arr 2 it doesn't change the CF though it should.

Do you know why is that happening?

Solution

• ``````mov [ARR1],1000000000000001b
mov [ARR2],1000000000000001b
mov [ARR1+1],0033h
mov [ARR2+1],0033h        ; ARR1/ARR2 contain 1, 51, 0, ?
``````

Your program defines 2 arrays that have each 2 word-sized elements. Because a word occupies 2 bytes in memory, assigning a value to the 2nd element must use an offset of +2. Assigning a value to the 3rd element would have to use an offset of +4, and so on.

``````mov [ARR1], 8001h
mov [ARR2], 8001h
mov [ARR1+2], 0033h
mov [ARR2+2], 0033h         ; ARR1/ARR2 contain 1, 128, 51, 0
``````
``````L1:
mov bx,k
sub bx,cx
``````

The inner loop (L2) is processing words but the outer loop (L1) advances through the array per byte. On the 1st outer iteration CX is 2 so BX = k - CX becomes 0, and on the 2nd outer iteration CX=1 so BX = k - CX becomes 1 which then will begin processing a word composed of the high byte from the 1st array element together with the low byte from the 2nd array element.
The good news is that you don't need that convoluted way (using BX) to walk through these arrays. Just add 2 to SI and DI on every iteration of the outer loop.

Your program contains a number of redundant instructions like `xor dx, dx` and unnecessary instructions like `clc`. For clarity you should remove these unproductive lines.

to check how much pairs of numbers have the same index (1 in arr 1 and the other in arr2) and are opposite

Knowing that the arrays hold each 2 elements, this means that the final result of your program will have to be a number in the range [0,2].

Without the forementioned errors your program would have worked fine, except that a solution that wipes out the arrays is not something I would have chosen.

``````    lea  si, [ARR1]      ; SI is address of 1st array
mov  [si], 8001h     ; Assign 1st element
mov  [si+2], 0033h   ; Assign 2nd element
lea  di, [ARR2]      ; DI is address of 2nd array
mov  [di], 8001h     ; Assign 1st element
mov  [di+2], 0033h   ; Assign 2nd element

mov  bp, k           ; Number of array elements
xor  dx, dx          ; Final result (will be 1 based on the fixed data)
L1:
mov  cx, [di]        ; CX is current element from 2nd array
mov  bx, [si]        ; BX is current element from 1st array
xor  ax, ax          ; AL is status byte, AH is a convenient 0
L2:
shr  bx, 1           ; The bit that comes out of BX
adc  al, ah          ;   is added to AL (that was zeroed beforehand)
shl  cx, 1           ; The bit that comes out of CX (at the opposite side)
sbb  al, ah          ;   is subtracted from AL
jnz  NOK             ; If both bits matched then AL would still be zero
test bx, bx          ; Has BX more ON bits ?
jnz  L2              ; Yes

; Early exiting if BX has no more ON bits
; If, at the same time, CX too has no more ON bits
; then an OK pair was found

test cx, cx
jnz  NOK
OK:
inc  dx              ; Found an OK pair
NOK:
add  si, 2           ; Next array element is 2 bytes higher in memory