assembly movsbl(%rax,%rcx,1)、%eax和$0xf、%eax的作用是什么?

fdx2calv  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(153)
movsbl (%rax, %rcx, 1),%eax
and $0xf, %eax

我有:

%rax=93824992274748
%eax=1431693628
%rcx=0

我真的不知道我有这些结果的原因是什么:第一条指令是如何得到%eax=97的?为什么971111的二进制表示之间的and会得到1

prdp8dxp

prdp8dxp1#

按位AND比较两个操作数的位。在本例中,97 AND 15:

0110 0001  ;97
0000 1111  ;15

对于每列位,如果列中的两位都是1,则该列中的结果位是1,否则是0。

0110 0001  ;97
0000 1111  ;15
---------------
0000 0001  ;1

你可能想知道这有什么用。事实上,你可以用AND做很多事情,其中很多乍一看并不明显。把一个操作数当作你的数据,另一个当作“过滤器”是非常有帮助的。
例如,假设我们有一个函数rand,每次调用它都返回一个%eax中的随机32位无符号整数,假设所有可能值的概率都相等,现在假设我们有一个函数myEvent,不管我们是否调用它都将基于rand的结果。如果我们希望这个事件有1/16的发生概率,我们可以这样做:

call rand
and $0xf, %eax
jnz skip
   call myEvent
skip:

这样做的原因是因为16的每一个倍数的最后4位都是清零的,所以这是我们唯一感兴趣的位,我们可以使用and $0xf, %eax忽略这4位左边的所有内容,因为它们在and之后都会变成零,一旦我们完成了and,我们就可以看看%eax是否包含零,如果包含,%eaxand之前包含16的倍数。
下面是另一个例子,它告诉你%eax是奇数还是偶数:

and $1, %eax
jnz isOdd

这是因为如果一个数的最右边的二进制数是1,那么它就是奇数。每当你在高级语言中执行n % 2时,编译器都会用n & 1来替换它,而不是执行实际的除法。

相关问题