Какие 2 случая не решаются с помощью этого кода? - PullRequest
1 голос
/ 27 июня 2019

Проблема состоит в том, чтобы найти, сколько раз последовательность 101b появляется в 16-битном числе, включая вращение.

Пример: в числе 1001011001010110b последовательность появляется 4 раза. 3, что вы можете видеть непосредственно (включая перекрывающуюся пару, которая разделяет бит 1) и одну поперечную от низкой до высокой. В частности, битовые индексы 1, 0, 15 (где бит 0 - самый правый бит)

Версия на иврите: (запрошено)

клев הוא מספר בגודל מילה המורכבת מארבעה Фурниббл של אבעה תווים שקולטים בסדר הבא: מהתו הראשון קולטים לוקחים את 4 סיביות שמאליות. מהתו השני שקולטים קולטים לוקחים את 4 סיביות ימניות. מהתו השלישי שקולטים קולטים לוקחים את 4 סיביות שמאליות. מהתו הרביעי שקולטים קולטים לוקחים את 4 סיביות ימניות. .ארבעה תווים N צריך לקלוט .אחד FourNibble מכל ארבעה תווים רצופים שקולטים מייצרים .fournibbles את המספרים שמייצרים שומרים במערך עבור כל מספר שקלטנו צריך למצוא כמה פעמים הרצף 101 נמצא במספר. הערה: צריך לבדוק את הרצף בצורה מעגלית. במספר הבינארי 010000101 הרצף מופיע פעמיים.

В примере, написанном на иврите, мой учитель написал, что последовательность появляется дважды.

Этот код работал для меня, и я проверил его с некоторыми числами. Я не понимаю для каких случаев это не работает.

DATASEG
N equ 3
address dw ?        ;a variable that stores address of a function
address2 dw ?       ;a variable that stores address of a function inside other function
msg1 db 'enter 4 characters'
input db 7*N dup (?)      ;The input of the user
FourNibbles dw N dup(0)   ;An array to store the FourNibbles
results db N dup(0)       ;An array to store the results
.
.
.
proc FindResults; A Function that pushes the FourNibble and the results index of this FourNibble to the BinaryCheck function
    pop[address]
    mov di,offset FourNibbles
    mov si,offset results
    mov dx,N
CheckThisFourNibble:
    call SaveRegisters
    push si
    push [di]
    call BinaryCheck
    call GetRegisters
    inc si
    add di,2
    loop CheckThisFourNibble
    push[address]
    ret
endp FindResults

proc BinaryCheck
   pop[address2]    ; the return address
   pop dx           ;The 16 bit input number
   pop bx           ;the result address.
   mov cx,16 
Check:   
   push dx
   and dx,0111b
   cmp dx,101b
   jne Again
   inc[byte ptr bx]
Again:
   pop dx
   rol dx,1
   loop Check
   push[address2]
   ret
endp BinaryCheck

1 Ответ

2 голосов
/ 27 июня 2019

В примере, написанном на иврите, мой учитель написал, что последовательность появляется дважды.

Пример "010000101".

010000101
      ***  1st
**      *  2nd

Но это происходит только в том случае, если вы выполняете перенос на 8-битной границе.Как 16-битное число, оно 00000000 010000101, и вы правильно обнаружите, что оно имеет только один 101.

Я не понимаю, для каких случаев оно не работает.

Вы не обнулили счетчик на [bx] заранее.Это, безусловно, тот случай, когда он не будет работать правильно.(Было бы проще вернуть значение счетчика в регистр, вместо того, чтобы вызывающий передавал указатель.)

А что с pop?Если это процедура, первый pop будет содержать обратный адрес.Обычный способ получить доступ к аргументам стека в 16-битном коде - создать указатель кадра с BP.

    push    bp
    mov     bp, sp
    mov     dx, [bp+4] ; The 16 bit number
    mov     bx, [bp+6] ; The results address
    mov     cx, 16
    mov     [bx], ch   ; CH=0
Check:   
    mov     ax, dx
    and     ax, 111b
    cmp     ax, 101b
    sete    al
    add     [bx], al
    ror     dx, 1
    dec     cx
    jnz     Check
    pop     bp
    ret     4

Или, если вам нужна версия, совместимая с 8086 (счет ZF = 1, результат из cmp без sete), см. ответы на Как узнать, сколько раз 101b отображается в числе?


Ваш номер "1001011001010110":

1001011001010110
           ***   1st
         ***     2nd
   ***           3rd
*             ** 4th

Из обновленного кода в вопросе :

loop CheckThisFourNibble

Регистр CX не инициализирован.Вы использовали DX для итерации, поэтому пишите:

dec dx
jnz CheckThisFourNibble
msg1 db 'enter 4 characters'

Я удивлен, что msg1 не имеет какой-тотерминатора как 0 или "$".

...