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).
精彩评论