【问题标题】:Assembly CMP result differs depending on used register?装配 CMP 结果因使用的寄存器而异?
【发布时间】:2013-05-09 14:17:23
【问题描述】:

我一直在从事我的装配项目,遇到了一个我无法理解的事实。

我有一个名为“lent”的单词数组,里面填充了一些数字。当我打印 0 索引下的内容时,它显示 ASCII 0 (NULL)。但是,当我使用 CMP 检查该值是否为 0 时,我遇到了一些麻烦。这是一些代码:

mov di,offset lent
mov cx,0d
cmp ds:[di],cx

它返回不等于,好像 [di] 不包含零。 然而:

mov di,offset lent
mov cl,0d
cmp ds:[di],cl

返回相等,这让我感到困惑。我需要第一个案例在我的代码中工作。 如果这是一个蹩脚的问题,我很抱歉,但我无法在互联网上找到合适的答案。提前致谢

【问题讨论】:

  • “当我打印 0 索引下的内容时,它显示 ASCII 0 (NULL)。” 你是打印整个单词还是只打印低字节?
  • 我是这样做的:mov dx,ds:[di] mov ah,2d int 21h
  • 那只会打印一个字符(来自DL,即低字节)。
  • 更具体地说:我需要ds:[lent] 等于offset tab,在代码中是这样的:mov di,offset tab | mov bx,offset lent | mov ds:[bx],di,但它不起作用。
  • 您能否显示代码的整个部分,您都在其中存储值,然后尝试与之进行比较? (而不仅仅是一部分)

标签: assembly x86-16 cmp


【解决方案1】:

Sparky 的回答是正确的。 为避免混淆和检测错误,请尝试使用大小前缀,如

mov di, offset lent
mov cl, 0d
cmp byte ptr [di], cl

如果你尝试使用单词 ptr 前缀,比如

cmp word ptr [di], cl

使用 debug.exe,它会显示一个错误消息。

【讨论】:

    【解决方案2】:

    第二种情况是将 的一个字节与 .此字节匹配 (ZF=1)。

    但是,第一种情况实际上是比较两个字节 和 .两个字节中只有一个匹配。因此,您得到 ZF=0。

    【讨论】:

      【解决方案3】:

      mov ds:[di] 到一个寄存器并查看它

      mov di,offset lent

      mov cx,0d

      cmp ds:[di],cx

      变成:

      mov di,offset lent

      mov cx,0d

      mov ax,[di]

      cmp al,cl

      cmp ax,cx

      cmp 啊,ch

      看一看,调试一下

      【讨论】:

      • 我得到了它的工作,尽管不完全理解为什么。我将 16 位变量(包含偏移量)移动到 16 位寄存器(不再是 mov si,ds:[lent])替换为将字节 ptr 移动到这样的变量到 8 位半寄存器中,所以它现在是 mov bl,byte ptr ds:[di](之后xor bx,bx 确保高部分也是空的)。我很难理解这一点......
      猜你喜欢
      • 2021-01-23
      • 2015-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多