Home > Enterprise >  how to check if 2 numbers have reversed bits in assembly?
how to check if 2 numbers have reversed bits in assembly?

Time:12-11

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?

CodePudding user response:

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.
Below is my implementation. Read the tail comments carefully!

    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
    add  di, 2
    dec  bp              ; Repeat for every element in the array(s)
    jnz  L1
  • Related