访问嵌入式X86组件中的特定位

时间:2010-11-09 23:43:49

标签: visual-studio-2010 assembly x86 inline-assembly

我正在尝试访问特定位并进行修改。 我已将0x01ABCDEF(十六进制值)移动到ecx中,并希望能够检查特定位置的位值。 例如,我必须取0x01ABCDEF(0xEF)的字节0 检查位置7的位是否为1 将中间的4位设置为1,其余的设置为0。

3 个答案:

答案 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)。