【问题标题】:Which 2 cases aren't solved with this code?这段代码没有解决哪两种情况?
【发布时间】:2019-11-09 03:26:24
【问题描述】:

问题是找出序列101b在包括旋转在内的16位数字中出现了多少次。

示例:在数字1001011001010110b 中,该序列出现了 4 次。 您可以直接看到的 3 个(包括共享 1 位的重叠对)和一个从低到高的环绕。特别是位索引 1、0、15(其中位 0 是最右边的位)

希伯来语版本:(要求)

nibble הוא מספר בגודל מילה המורכבת מארבעה Fournibble של אבעה תווים שקולטים בסדר הבא: מהתו הראשון קולטים לוקחים את 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

【问题讨论】:

  • 代码看起来正确。您在标题中指的是哪两种情况?
  • 在您的示例中,您指定 10101 计为两个匹配项,也许测试用例不允许对多个匹配项使用相同的位?
  • @MargaretBloom 她没有告诉我它们是什么。我应该在做我的项目时考虑所有情况(这段代码是其中的一部分),我认为这段代码应该适用于所有这些,所以我不知道我的老师说这对他们不起作用的两种情况是什么意思。她在测试中告诉我,要更改解决方案,这样它就不会出现循环,它会解决它。但是我不知道从哪里开始或做什么,因为我不知道这些情况是什么。
  • @MichaelPetch 我会翻译它。您需要找到序列 101b 在数字中出现的次数。注意:您需要以循环方式检查数字(最后 3 个单词是用谷歌翻译翻译的)。我确定这个例子是正确的,它是不过轮换,因为我不明白作业,让我的老师给我解释一下,她就是这么给我解释的。
  • @MichaelPetch 它是希伯来语的。我应该只发布她给出的例子吗?

标签: assembly binary masm x86-16


【解决方案1】:

在用希伯来语版本编写的示例中,我的老师写道,序列出现了两次。

示例是“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),请参阅 How can I find how many times does 101b show in the number? 上的答案


你的号码“1001011001010110”:

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

来自问题中的更新代码

loop CheckThisFourNibble

CX 寄存器未初始化。你已经使用DX 进行迭代,所以写:

dec dx
jnz CheckThisFourNibble
msg1 db 'enter 4 characters'

我很惊讶 msg1 没有像 0 或 "$" 这样的终结符。

【讨论】:

  • 我用0初始化了它的地址在bx中的数组。现在我已经发布了整个函数,这不是第一次弹出。
  • 如果课程是 8086,您对 sete 的使用可能无效。他们可能无法访问 386 指令集和sete。如果我教的是 8086 课程,我不会接受 sete 的回答。
  • 虽然非正统(而且不是普通人从堆栈中获取参数的方式),但他们所做的在技术上是正确的。他们将返回地址弹出到全局中,然后在最后恢复返回地址。他们是否打算成为被调用者清理的堆栈很难说,但同意这就是他们的代码所做的。
  • @TheNiv:我更新了这个答案,提到了 8 位与 16 位的数字差异,为您的程序如何将数字视为 16 位添加了显式的前导零。这已经在您之前的一个问题的答案或 cmets 中提到过。目前尚不清楚 8 位与 16 位轮换的规则应该是什么。如果数字是<= 0xFF,你应该使用 8 位循环吗?
  • @PeterCordes :在原始的希伯来语中,他们谈论数字,我同意他们也给出了一个 8 位值的示例,即 number。也许他们说数字的任何地方都是byte?该示例将 16 位数字划分为 [10010110] [01010110] 。我之所以这么想,是因为老师似乎在示例中定义了“数字”。那么错过的 2 种情况(每个字节)将是事物在字节边界(而不是 16 位字)上包装的地方。我曾希望你用希伯来语提出的整个原始问题会有所帮助,但我只有更多问题,哈哈
猜你喜欢
  • 2011-10-16
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多