以x86汇编语言获取EAX寄存器的第一位

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以x86汇编语言获取EAX寄存器的第一位相关的知识,希望对你有一定的参考价值。

在x86汇编语言中,是否可以获得寄存器的第一位?我想获得eax寄存器的第一位并将其移至ebx,但我不知道该如何做到这一点。

.stack 2048

.data

ExitProcess proto, exitcode:dword 

.code
start:
mov eax, 3;
;now I want to move the first bit of eax into ebx. How can I obtain the first bit from eax?
invoke  ExitProcess, 0
end start
答案

如果通过“第一位”表示最低有效位,则尝试:

 ...
 mov   ebx, eax
 and   ebx, 01

你显然不明白指令一次对命名寄存器中的所有位进行操作,而“和”指令逐位组合它们的操作数。

以下工作也是如此,可以说是对您的请求的更直接的解释(“获取eax的第一位,然后放入EBX”)但它会破坏EAX的内容:

 ...
 and   eax, 1
 mov   ebx, eax

在汇编代码中,由于您的寄存器很少,它们的内容往往很珍贵,因此通常可以避免在计算新结果时破坏一个寄存器的内容。 (当你不能,你不能,但这种情况很容易避免)。

最后,你可以写:

 ...
 mov   ebx, 1
 and   ebx, eax

这很好用,和其他两个一样快。我更喜欢第一个,因为它强调恕我直言,因为首先提到它,而不是“1”,这只是一个偶然的常数,我关心的价值(EAX的内容)。这种风格看起来似乎并不重要,但是如果你编写了很多代码,特别是汇编程序等神秘的东西,那么为了最大限度地提高后续可读性而做的事情是值得的。

找到英特尔参考手册是值得的,并仔细阅读它们以了解每台机器指令的作用。这似乎是一项艰巨的任务,因为它是一本大书;只关注您最初似乎需要的说明。

另一答案

从寄存器中获取一个位涉及使用掩码的and操作,该掩码在感兴趣的位位置具有1,在所有其他位中具有0。然后可选地,使用rotate rightrotate left将位移动到结果中的所需位置。

另一答案

您还可以使用程序集的rotation属性,即使用bit指令将指定位复制到进位标志中,我们可以使用rotation-carry标志指令。

我认为这对于理解在使用和放置爆破位的位置和方式方面的进展非常有效。

另一答案

如上所述,使用movand是最快的解决方案,但编程的有趣部分是可以找到解决单个问题的许多解决方案,因此作为一种效率较低的替代方案,您可以使用以下代码之一。

所以你也可以像这样解决它:

xor ebx, ebx ; sets ebx = 0
TEST eax, 1 ; is the lowest bit set?
JZ skip_add ; if low bit is zero, skip next instruction

; if lowest bit was set / AND op resulted not zero
add ebx, 1 ; ebx += 1, or use `INC ebx`

skip_add:
; process the result

或者,您也可以使用:

xor ebx, ebx ; ebx = 0
shr eax, 1 ; shift right: lowest bit in carry flag now
adc ebx, 0 ; ebx += 0 + carry bit
shl eax, 1 ; get back original value of eax, `shl` and `or` with ebx
or eax, ebx ; or use `push eax` and `pop eax` instead

另一种选择(类似于其他答案,但更加省力):

push eax
and eax, 1
xchg ebx, eax ; swap contents, could also use `mov` here
pop eax

请注意,这两个解决方案都不会更改eax中的值,因此您仍然可以自由地使用eax中的值。另请注意,评论值适用于值为3的eax,因为问题中使用了mov eax, 3

如果您已经知道,ebx为零,您可以跳过xor线,如果更改eax无关紧要,您也可以删除shl操作。因此,您可以看到实际操作是通过大约两条指令完成的。关于μops,请参阅Peter的评论。

另一答案

......第一位:

test eax, 1
setz ebx

短剑

以上是关于以x86汇编语言获取EAX寄存器的第一位的主要内容,如果未能解决你的问题,请参考以下文章

试图理解这个汇编 x86 代码

汇编指令和寄存器

C语言怎么取CPU的各项信息?

在 X86 程序集中访问和移动字节

X86 操作码将 xmm 寄存器移动到通用寄存器

汇编初识