user350034
user350034

Reputation:

Scan for first zero bit (Assembly)?

I have some numbers in AH, AL, BL and BH registers. I need to check whether there is at least one 0 bit in each of the registers in high nibble of the number. If there is, then put into the variable called check 10, otherwise, -10.

Here's what I tried:

org 100h
check dw 0
mov ah, 11011111b
mov al, 11011111b
mov bl, 11011111b
mov bh, 11011111b 

mov check, 10
and ax, 0F0F0h
cmp ax, 0F0F0h
je no_all_zeros
and bx, 0F0F0h
cmp bx, 0F0F0h
jne has_zeros
no_all_zeros:
mov check, -10
has_zeros:

ret

Upvotes: 1

Views: 2846

Answers (5)

user350034
user350034

Reputation:

The right way to do this would be:

.MODEL SMALL
.STACK 100h

.DATA
check DB 10
.CODE
mov ax, @DATA
mov ds, ax
xor ax, ax
xor bx, bx
xor cx, cx

; Assign values   
mov cl, 4 ; Assign rotator - 4 bits
mov ax, 1011101010111010b
mov bx, 1110100010110100b

; Check AX
xor ax, 0F0F0h ; masking
shr ah, cl ; rotating and expecting other than 0
cmp ah, 0 ; ah = 0 ?
je noZero
shr al, cl
cmp al, 0
je noZero
xor bx, 0F0F0h
shr bh, cl
cmp bh, 0
je noZero
shr bl, cl
cmp bl, 0
je noZero
jmp exit
noZero:
mov check, -10
exit:
mov ah, 4ch
int 21h

Upvotes: 0

ruslik
ruslik

Reputation: 14870

    mov check, 10
    and ax, bx
    and ax, F0F0h
    cmp ax, F0F0h
    jne has_zeros
    mov check, -10
has_zeros:

EDIT finally I understand what you want: the result should be -10 if at least one has 0xF in its high nibble:

    mov check, -10
    xor  ax, F0F0h
    test ax, F000h
    je   no_zero
    test ax, 00F0h
    je   no_zero
    xor  bx, F0F0h
    test bx, F000h
    je   no_zero
    test bx, 00F0h
    je   no_zero
    mov check, 10
no_zero:

Upvotes: 0

Jim Mischel
Jim Mischel

Reputation: 133995

If you just need to see if there is a 0 bit in AH, then compare against 0xFF. If the compare isn't equal, then there is at least one 0 bit. Same with the other registers.

If you really want to find the first 0 bit, you can do it with multiple shifts. Or you can use the BSF instruction (assuming 80386 assembly), although you'll need to negate the operand and search for the first set bit.

Finally, there is an alternative to using the multiple shifts if you can't use BSF. I think the Bit Twiddling Hacks has an example. It'll be in C, but converting to assembly shouldn't be too tough.

Edit, after your info:

So you want to see if the upper nibble of each register contains at least one 0 bit? And you don't want to change the registers that contain the values.

mov cx, ax
and cx, 0xF0F0 ; this clears the low nibbles so you don't have to worry about them
xor cx, 0xF0F0 ; CX will be non-zero if there were bits set in the high nibbles
jz NoZeros
; Here you'll need to check CH and CL individually to see if they're both non-zero

Upvotes: 4

Brendan
Brendan

Reputation: 37214

should give 10 only when in all the numbers in registers there is at least one zero bit in left half

This should work:

    mov [check], -10

    add al,0x10
    mov al,0
    adc ax,0x1000
    adc al,0
    add bl,0x10
    adc al,0
    add bh,0x10
    adc al,0
                      ;al = number of high nibbles that had all bits set

    test al,al        ;Did any high nibble have all bits set?
    jne .l1           ; yes, check = -10
    mov [check], 10   ; no, check = 10
.l1:

Edit: If you don't want to replace the values in registers, then push ax and bx on the stack and pop them afterwards..

Upvotes: 0

JimR
JimR

Reputation: 16113

cmp AH, FFh
jl has_zeros

Looks like it would work to me, but I'm assuming by left half you mean the upper 8 bits. Could be wrong though.

Upvotes: 0

Related Questions