字节序与按位比较寄存器之间的相互作用

时间:2015-08-04 20:23:05

标签: x86

我相信这段代码是有效的,但它看起来似乎不应该,除非将ax与0000 1010而不是1010 0000进行比较。是不是无论数据是存储在小还是大都不重要endian格式?

以下是相关的代码:

mov    al, es:100h
mov    ah, 0
and    ax, 0A0h
cmp    ax, 20h
...

这个价值是不是像这样:

mov    al, es:100h  ; ax = ???? ????
mov    ah, 0        ; ax = 0000 ????
and    ax, 0A0h     ; ax = 0000 0000 or ax = 0000 ?0?0
cmp    ax, 20h      ; only useful if ax = 0000 ?0?0
...

显然,这里有一条我不知道的规则。解释会非常有用。

编辑:我应该提一下,我已经找到了答案,却找不到答案。例如,这个线程只是让它看起来更像代码必须是错误的。但我非常有信心它有效:Bitwise operators and "endianness"

3 个答案:

答案 0 :(得分:2)

我不认为这里有问题。你的第一条指令是:

mov    al, es:100h

这将在最低有效字节中存储任意值。接下来你做:

mov    ah, 0

这会将最重要的字节清零。因此ax介于00xff之间。

现在,您and使用值0xA0

and    ax, 0A0h

最后你将ax寄存器与值0x20进行比较:

cmp    ax, 20h

在这一系列操作中,任何时候都不会发挥字节顺序因素。考虑:

mov    al, es:100h ;         ax = ???? ???? ???? ????
mov    ah, 0       ;         ax = 0000 0000 ???? ????
and    ax, 0A0h    ;         ax = 0000 0000 ?0?0 0000
cmp    ax, 20h     ; compare with 0000 0000 0010 0000

或者我们可以用反转的字节写这个,这样最重要的字节就在右边:

mov    al, es:100h ;         ax = ???? ???? ???? ????
mov    ah, 0       ;         ax = ???? ???? 0000 0000
and    ax, 0A0h    ;         ax = ?0?0 0000 0000 0000
cmp    ax, 20h     ; compare with 0010 0000 0000 0000

正如您所看到的,无论字节顺序如何,都应该得到完全相同的结果。

答案 1 :(得分:1)

Endian-ness仅在从内存中提取多字节值时很重要。在您的示例中,第一行从内存中获取单个字节,因此endian-ness不是问题。

当您在汇编中对常量进行硬编码时,它们从左到右阅读,就像普通数字一样。因此,常量0A0h具有00000000作为高字节(对应于ah)而10100000作为低字节(对应于al)。

您似乎对寄存器中的位数感到困惑。 AX是16位寄存器。所以使用二进制文件来评论代码,评论应该是

mov    al, es:100h  ; ax = ???? ???? ???? ????
mov    ah, 0        ; ax = 0000 0000 ???? ????
and    ax, 0A0h     ; ax = 0000 0000 ?0?0 0000
cmp    ax, 20h      ; compare with 0000 0000 0010 0000

答案 2 :(得分:0)

AFAICT,mov ah, 0cmp后的旗帜没有影响。 ax的上半部分已被and ax, 0A0h归零。

根据您要分支的条件,and设置的标志可能就足够了。您遗漏了下一条指令,因此我们无法告诉您代码实际正在测试的内容,以及是否可以仅使用test代替and / cmp来完成。

相关问题