开发者

Access specific bit in embedded X86 assembly

I am trying to acces a specific bit and modify it. I have 开发者_StackOverflow社区moved 0x01ABCDEF (hex value) into ecx and want to be able to check bit values at specific position. For example I must take byte 0 of 0x01ABCDEF (0xEF) check if bit at position 7 is 1 set the middle 4 bits to 1 and the rest to 0.


Under x86 the most simple solution is using bit manipulation instructions like BT (bit test), BTC (bit test and complement), BTR (bit test and reset) and BTS (bit test and set).

Bit test example:

mov      dl, 7      //test 7th bit
bt       ecx, edx   //test 7th bit in register ecx 

Remember: only last 5 bits in register edx is used.

or

bt       ecx, 7

In both cases the result is stored in carry flag.


It's been years since I've done asm, but you want to and your value with 0x80 and if the result is zero your bit is not set so you jump out, otherwise continue along and set your eax to the value you want (I assume the four bits you mean are the 00111100 in the fourth byte.

For example (treat this as pseudo code as it's been far too long):

      and eax, 0x80         
      jz  exit
      mov eax, 0x3C
exit: 


Most CPUs do not support bit-wise access, so you have to use OR to set and AND to clear bits. As I'm not really familiar with assembly I will just give you C-ish pseudocode, but you should easily be able to transform that to assembly instructions.

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)
}

Not that you can remove the last_byte assignment and directly check value & 0x40. However, if you want to check something which is not the least significant part, you have to do shifting first. For example, to extract ABCD you would use the following:

middle_bytes = (value & 0xFFFF00) >> 8;

value & 0cFFFF00 gets rif og the more significant byte(s) (0x01) and >> 8 shifts the result left by one byte and thus gets rid of the last byte (0xEF).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜