我无法弄清楚出了什么问题。我花了几个小时试图调试这个。我正在使用gcc -m32 source.c -o source
进行编译调试时如何处理此问题?现在,我正在以多种不同的方式隔离代码,一切都按照我的预期进行,但是当我将它们放在一起时,它的工作方式是错误的。
该程序接受输入,然后用1位查找最高位置。
我暂时删除了我的代码。
答案 0 :(得分:3)
在bitsearch中,您将num
存储在eax
中,在edx
中存储特殊值以执行check
。 check
正在测试是否设置了最高位(表示负数),如果是这样则退出...
andl
中的check
指令将操作结果存储在第二个操作数(eax
)内,因此结果将覆盖num
。
然后在zero
中使用edx
执行计算... edx
包含函数开头的特殊值,因此结果总是错误的。< / p>
现在在zero
结束时,您将回到check
,但此处不需要检查,您应该回到zero
而不是......
答案 1 :(得分:1)
是否需要在汇编中实现位搜索?一个简单的for
循环可以完成相同的任务,并且更具可读性:
int num = 10;
int maxFound = -1;
for (int numShifts = 0; numShifts < 32 && num != 0; numShifts++) {
if ((num & 1) == 1) {
maxFound = numShifts;
}
num = num >> 1;
}
//the last position that had a 1 will be in maxFound
答案 2 :(得分:1)
有一个简洁的诀窍:x&amp; -x隔离最后的1位。以下C程序使用基于de Bruijn序列的查找表来计算常量(!)时间内数字的尾随(!)零的数量:
unsigned int x; // find the number of trailing zeros in 32-bit x
int r; // result goes here
int table[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
r = table[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
用汇编语言(我在16岁时停止学习)这样做应该没问题。现在你所要做的就是反转num中的位并应用上述技术。
我写了一篇关于上述技巧的论文,但遗憾的是它并没有在网上提供。如果您有兴趣,我可以通过电子邮件将其发送给您(或任何其他感兴趣的人)。
答案 3 :(得分:-2)
我的装配知识有点生疏,但在我看来bitsearch
过于复杂。如何只是将数字向右旋转并计算你需要做的时间直到它为零?