我正在尝试访问特定位并进行修改。 我已将0x01ABCDEF(十六进制值)移动到ecx中,并希望能够检查特定位置的位值。 例如,我必须取0x01ABCDEF(0xEF)的字节0 检查位置7的位是否为1 将中间的4位设置为1,其余的设置为0。
答案 0 :(得分:3)
自从我完成asm以来已经好几年了,但是你想要和你的值一起使用0x80,如果结果是零,你的位没有被设置,所以你跳出来,否则继续并将你的eax设置为你想要的值(我假设你的四位是第四个字节中的00111100。
例如(将其视为伪代码,因为它太长了):
and eax, 0x80
jz exit
mov eax, 0x3C
exit:
答案 1 :(得分:2)
在x86下,最简单的解决方案是使用位操作指令,如BT(位测试),BTC(位测试和补码),BTR(位测试和复位)和BTS(位测试和设置)。
位测试示例:
mov dl, 7 //test 7th bit
bt ecx, edx //test 7th bit in register ecx
请记住:只使用寄存器edx中的最后5位。
或
bt ecx, 7
在这两种情况下,结果都存储在进位标志中。
答案 2 :(得分:1)
大多数CPU不支持逐位访问,因此必须使用OR来设置和AND来清除位。 由于我不熟悉汇编,我只会给你C-ish伪代码,但你应该很容易将其转换为汇编指令。
value = 0x01ABCDEF;
last_byte = value & 0xFF; // = 0xEF
if (last_byte & 0x40) { // is the 7th bit set? (0x01 = 1st, 0x02 = 2nd, 0x04 = 3rd, 0x08 = 4th, 0x10 = 5th, 0x20 = 6th, 0x40 = 7th, 0x80 = 8th)
value = value & 0xFFFFFF00; // clear last byte
value = value | 0x3C; // set the byte with 00111100 bits (0x3C is the hex representation of these bits)
}
并非您可以删除last_byte作业并直接检查value & 0x40
。但是,如果你想检查一些不是最不重要的部分,你必须先进行转移。例如,要提取ABCD,您将使用以下内容:
middle_bytes = (value & 0xFFFF00) >> 8;
value & 0cFFFF00
得到rif og更重要的字节(0x01)和>> 8
将结果左移一个字节,从而摆脱最后一个字节(0xEF)。