movsbl (%rax, %rcx, 1),%eax and $0xf, %eax
我有:
%rax=93824992274748 %eax=1431693628 %rcx=0
我真的不知道我有这些结果的原因是什么:第一条指令是如何得到%eax=97的?为什么97和1111的二进制表示之间的and会得到1?
%eax=97
97
1111
and
1
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的发生概率,我们可以这样做:
rand
%eax
myEvent
call rand and $0xf, %eax jnz skip call myEvent skip:
这样做的原因是因为16的每一个倍数的最后4位都是清零的,所以这是我们唯一感兴趣的位,我们可以使用and $0xf, %eax忽略这4位左边的所有内容,因为它们在and之后都会变成零,一旦我们完成了and,我们就可以看看%eax是否包含零,如果包含,%eax在and之前包含16的倍数。下面是另一个例子,它告诉你%eax是奇数还是偶数:
and $0xf, %eax
and $1, %eax jnz isOdd
这是因为如果一个数的最右边的二进制数是1,那么它就是奇数。每当你在高级语言中执行n % 2时,编译器都会用n & 1来替换它,而不是执行实际的除法。
n % 2
n & 1
1条答案
按热度按时间prdp8dxp1#
按位AND比较两个操作数的位。在本例中,97 AND 15:
对于每列位,如果列中的两位都是1,则该列中的结果位是1,否则是0。
你可能想知道这有什么用。事实上,你可以用AND做很多事情,其中很多乍一看并不明显。把一个操作数当作你的数据,另一个当作“过滤器”是非常有帮助的。
例如,假设我们有一个函数
rand
,每次调用它都返回一个%eax
中的随机32位无符号整数,假设所有可能值的概率都相等,现在假设我们有一个函数myEvent
,不管我们是否调用它都将基于rand
的结果。如果我们希望这个事件有1/16的发生概率,我们可以这样做:这样做的原因是因为16的每一个倍数的最后4位都是清零的,所以这是我们唯一感兴趣的位,我们可以使用
and $0xf, %eax
忽略这4位左边的所有内容,因为它们在and
之后都会变成零,一旦我们完成了and
,我们就可以看看%eax
是否包含零,如果包含,%eax
在and
之前包含16的倍数。下面是另一个例子,它告诉你
%eax
是奇数还是偶数:这是因为如果一个数的最右边的二进制数是1,那么它就是奇数。每当你在高级语言中执行
n % 2
时,编译器都会用n & 1
来替换它,而不是执行实际的除法。