访问嵌入式 X86 汇编中的特定位

发布于 2024-10-01 02:52:37 字数 136 浏览 5 评论 0原文

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

I am trying to acces a specific bit and modify it.
I have 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜`诱少女 2024-10-08 02:52:37

在 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

在这两种情况下,结果都存储在进位标志中。

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.

好久不见√ 2024-10-08 02:52:37

我已经完成asm很多年了,但是你想用0x80和你的值,如果结果为零,你的位没有设置,所以你跳出,否则继续,并将你的eax设置为你想要的值(我假设 例如,您所说的四位是第四个字节中的 00111100

(将其视为伪代码,因为它太长了):

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

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: 
暗藏城府 2024-10-08 02:52:37

大多数 CPU 不支持按位访问,因此必须使用 OR 来设置位,使用 AND 来清除位。
由于我不太熟悉汇编,所以我只会给您 C 风格的伪代码,但您应该能够轻松地将其转换为汇编指令。

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 获取较高有效字节 (0x01) 和 >> 8 将结果左移一个字节,从而去掉最后一个字节 (0xEF)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文