2011-01-01 4 views
1

У меня есть некоторые цифры в AH, AL, BL и BH регистры. Мне нужно проверить, есть ли хотя бы один 0 бит в каждого регистра в высокий nibble из числа. Если есть, то введите в переменную check 10, в противном случае -10.Сканировать первый бит нуля (сборка)?

Вот что я пробовал:

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 

ответ

0

Righ т способ сделать это было бы:

.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 
4

Если вам просто нужно увидеть, если есть 0 бит в АХ, а затем сравнить с 0xFF. Если сравнение не равно, то есть хотя бы один 0 бит. То же самое с другими регистрами.

Если вы действительно хотите найти первый 0 бит, вы можете сделать это с несколькими сменами. Или вы можете использовать инструкцию BSF (предполагая сборку 80386), хотя вам нужно будет отменить операнд и выполнить поиск первого бита.

Наконец, существует альтернатива использованию нескольких сдвигов, если вы не можете использовать BSF. Я думаю, пример Bit Twiddling Hacks. Это будет в C, но преобразование в сборку не должно быть слишком жестким.

Edit, после информации:

Так что вы хотите увидеть, если верхняя клев каждого регистра содержит, по меньшей мере, один бит 0? И вы не хотите менять регистры, содержащие значения.

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 
+1

Учитывая 8086 16 бит, и он хочет, чтобы левая половина (верхняя грызть, я предполагаю), что он не должен 'and' с 0xFF00, а не (?) 0xFF? –

+0

Прежде всего, я не хочу заменять значения в регистрах, поэтому я предполагаю, что это должен быть ТЕСТ. Другое дело, что это субрегистры. В 8086 году они 8 бит. Так что это должно быть 0xF0 нет (учитывая, что мне нужно сканировать только левую половину чисел - левые 4 бита)? –

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

EDIT наконец, я понимаю, что вы хотите: результат должен быть -10, если хотя бы один имеет 0xf в высоком клев:

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: 
+0

@cthulhu: переписан – ruslik

0
cmp AH, FFh 
jl has_zeros 

Looks как это сработало бы для меня, но я предполагаю, что в левой половине вы имеете в виду верхние 8 бит. Может быть, неправильно.

0

должен дать 10 только тогда, когда во всех чисел в регистрах есть по крайней мере один нулевой бит в левой половине

Это должно работать:

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: Если вы не хотят заменять значения в регистрах, а затем толкать топор и bx на стеке и затем наносить их потом.

Смежные вопросы