如何在汇编中测试位域?

编程语言 2026-07-10

我正在用x86_16汇编为VBE解析进行一些测试。我需要测试某些属性标志的位域,但我不确定最佳做法。当前的解决方案是这个,我拼凑出来的:

mov ax, word[vbe_mode.attributes] ; The bitfield I'm checking.
and ax, 0b0000000010011001        ; The fields I'm trying to check for.
cmp ax, 0b0000000010011001
jne .missing_flags

但我确信还有更高效的方法。这会是什么?test,在这种情形通常很有用,但它没有“非排他性”的版本,所以如果有一个我不关心的标志被开启,我就不能忽略它!

解决方案

我将以代码大小作为衡量标准,因为你还没有指定一个具体的CPU,用来计算时钟周期,而且显然这段指令序列的耗时会被前面的BIOS调用所淹没。

据说感兴趣的位都在低字节,因此我们可以用8位指令来完成,这样可能更短。由于我们把所有操作都放在AX中,我们有“累加器-立即数”ALU指令;8位指令是2 字节(操作码加1 字节立即数),16位指令是3 字节(操作码加2 字节立即数)。

你的解决方案于是是

mov ax, [addr]                    ; 3 bytes
and ax, 0b0000000010011001        ; 3
cmp ax, 0b0000000010011001        ; 3
jne missing_bits                  ; 2

总共11字节。

通过使用AL而不是AX,利用带累加器、立即数操作数的常见指令的短格式编码的特性(这只有在AL上才会显著缩短,其他8 位寄存器不会):

mov al, [addr]     ; 3 bytes
and al, 0b10011001 ; 2
cmp al, 0b10011001 ; 2
jne missing_bits   ; 2

下面的若干个16位选项可以改造成同等长度的解法,但我没有找到更短。


如果感兴趣的位跨越字的两个字节,那么 编译器的做法 is the equivalent of

mov ax, [addr]    ; 3 bytes
not ax            ; 2
test ax, mask     ; 3
jnz missing_bits  ; 2

so that "all these bits should be 1" is transformed into "all these bits should be 0". Then after masking off the other bits, we are checking for the entire register to be zero, which is given to us by the zero flag.

We can get one byte shorter by doing

mov ax, [addr]      ; 3 bytes
or ax, ~mask        ; 3
inc ax              ; 1
jnz missing_bits    ; 2

By ORing with the complement of the mask, all the desired bits were set if and only if the result is all-bits-1, or -1 in two's complement; then adding 1 results in 0.

This takes advantage of the single-byte inc encoding, but note that it's 16-bit only (or 32-bit in 32-bit mode); using inc al in the 8-bit solution would be 2 bytes. Also, these encodings were removed entirely in 64-bit mode (they were reused for the REX prefixes).

As far as speed is concerned, Peter Cordes noted that some older machines can only fuse test / jcc or cmp / jcc into a single uop, while newer CPUs (Sandy Bridge系列and Zen 3及以后) can also fuse inc / jcc.

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章