曲径通幽论坛

标题: 布尔逻辑与位测试 [打印本页]

作者: beyes    时间: 2010-2-12 21:25
标题: 布尔逻辑与位测试
1、布尔逻辑
提供布尔逻辑操作的有如下几个指令:
AND, NOT, OR, XOR

AND、OR 和 XOR 指令使用相同的格式:
and source, destination
其中,source 可以是8位,16位或者 32位的立即数、寄存器或内存中的值,destination 可以是 8位,16位或者是32位寄存器或内存中的值,但不能同时使用内存值作为源和目标操作数。

NOT 指令使用单一操作数。

使用 XOR 指令进行异或清零寄存器要比 MOV 指令加载一个立即数 0 到寄存器中要高效得多。

2、位测试
有时需要确定一个寄存器里的某一位是否被设置为1,如检查 EFLAGS 寄存器中的某一位,但我们往往只是想知道寄存器中某一位的设置情况而并不希望去改变这个位。这时可以使用 TEST 指令更好的达到这样的目的。

使用 TEST 指令,尽管没有数据写入目标位置,但仍然必须指定任意立即值作为源值。

下面用检查处理器是否支持 CPUID 指令来说明 test 指令的使用:
EFLAGS 寄存器中的 ID 标志 (第 21 位) 用于确定处理器是否支持 CPUID 指令。如果可以修改 ID 标志,则说明 CPUID 指令可用,否则不可用。为了进行测试,必须先获得 EFLAGS 寄存器,然后对其反转,然后再测试反转是否成功,查看它是否真的改变了。下面是测试程序:
# cpuidtest.s - An example of using the TEST instruction

.section .data
output_cpuid:
    .asciz "This processor suports the CPUID instruction\n"
output_nocpuid:
    .asciz "This processor does not support the CPUID instruction\n"

.section .text
.global _start
_start:
    nop
    pushfl
    popl %eax
    movl %eax, %edx
    xor $0x00200000, %eax    # change cpuid bit
    pushl %eax       
    popfl            # save the change
    pushfl
    popl %eax
    xor %edx, %eax       
    jnz cpuid
    pushl $output_nocpuid    # can not change the cpuid bit
    call printf
    add $4, %esp
    pushl $0
    call exit
cpuid:                # change successfully
    pushl $output_cpuid
    call printf
    add $4, %esp
    pushl $0
    call exit
编译连接
as -gstabs -o cpuid.o cpuid.s
 ld -dynamic-linker /lib/ld-linux.so.2 -lc -o cpuid cpuid.o
运行与输出
./cpuid
This processor suports the CPUID instruction
由上可见,处理器支持 CPUID 指令,因为 EFLAGS 中的第 21 位可以被改变。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2