|
1、布尔逻辑
提供布尔逻辑操作的有如下几个指令:
AND, NOT, OR, XOR
AND、OR 和 XOR 指令使用相同的格式:其中,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 位可以被改变。 |
|