如何在Motorola 68000汇编中将奇数转换为偶数,或反之?

4

如果我在单元格D1中有一个数字,并希望它始终为偶数,该如何确保它永远不是奇数?

我知道这与AND指令有关。但是当我尝试过后,它总是会减去1。所以它会将奇数转换为偶数,偶数转换为奇数。

基本上,我应该如何执行如果n是奇数,则减去1的操作?


1
因此,它会将奇数变成偶数,将偶数变成奇数:AND不能设置位,只能清除它们或保留它们设置,所以它不能使偶数变为奇数。 因此,您使用AND的尝试必须存在错误,使其执行其他操作。(XOR与1会翻转低位,在奇数和偶数之间翻转。ADD 1也会这样做,但会进位到高位。)无论如何,希望通过这些答案+内置于easy68k的调试器,您可以弄清楚您实际执行了什么。 - Peter Cordes
“...AND指令。但是当我尝试时,它总是会减去1。”这是不可能的。如果你真的相信这一点,应该尝试产生一个MCVE,但你应该自己弄清楚and并不总是减去1(例如(12 and 254) = 12…只有像(13 and 254) = 12这样的情况可能看起来像减1)。 - Ped7g
5个回答

5

and命令将您的数字与-2进行操作。

在二进制补码表示法中,-2是一个所有位都设置为1除了最低位的数(11111...110),因此,用作掩码时,它总是只清除您数字的最低有效位。这迫使它成为偶数(即使对于负数也能正常工作)。


至于标题中的“反之亦然”,要执行相反操作(即将每个偶数强制转换为下一个奇数),只需使用or命令并加上1。这将使最低有效位设置为1,从而获得所需的效果。


4
二进制中,奇数以1结尾,偶数以0结尾。你真正想要的是使最后一位二进制数字变成0,无论它最初是什么。(这将从奇数中减去1,而让偶数保持不变。)
做到这一点的方法是与1111...1110进行按位与运算,其中所有二进制数字都是1,除了最后一位是0。你可以通过对0000...0001进行按位取反来构造它,这当然只是1
因此,如果你的数字是n,你需要计算n & (~1)

3

只需要清除底部一位,所以虽然其他人使用了长字指令,但使用AND的字节形式也没有问题。

AND.B #0xFE, D1   ; make even
OR.B  #0x01, D1   ; make odd
XOR.B #0x01, D1   ; toggle even/odd

无论D1中的值大小是byte、word还是longword,您仍然清除了底部位,并保持寄存器中的所有其他位不变。
或者,您也可以:
BCLR #0,D1  ; make even
BSET #0,D1  ; make odd
BCHG #0,D1  ; toggle even/odd 

3

68000 CPU实际上有单独的位设置和位清除命令。在像你这样的情况下,明确地清除操作数的第0位可能会更简单和更清晰,而不需要回到布尔逻辑:

bclr.l #0,d0

替代

and.l $fffffffe,d0

1
对于一个16位数字,请执行以下操作:
EvenNumber = (D1 & 0xFFFE);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接