如何在 Motorola 68000 Assembly 中将奇数变成偶数,反之亦然?
How can I turn an odd number even, or vice versa, in Motorola 68000 Assembly?
基本上如果我在 D1 中有一个数字,并且希望它始终是偶数,我如何确保它永远不会是奇数?
我知道和AND指令有关。但是当我尝试这样做时,它总是会减去 1。所以它会将奇数变为偶数,将偶数变为奇数。
基本上我该怎么做if n is odd, sub 1
奇数在二进制中以1
结尾,偶数在二进制中以0
结尾。您真正想要的是使最后一个二进制数字成为 0
,而不管它的开头是什么。 (这将从奇数中减去 1,并保持偶数不变。)
这样做的方法是与 1111...1110
进行与运算,其中除最后一位 0
外,所有二进制数字都是 1
。您可以通过对 0000...0001
进行按位求反来构造它,这当然只是 1
.
因此,如果您的号码是 n
,您想要计算 n & (~1)
。
and
您的电话号码 -2
。
在 2 的补码表示中,-2 是一个除最低位 (11111...110) 之外的所有位都设置为 1 的数字,因此,用作掩码时,它总是只删除数字的低位。这迫使它成为偶数(即使是负数也能正常工作)。
至于标题中的"viceversa":做相反的事情(=强制每个偶数到下一个奇数),只是or
和1
。这样就把低位设置为1,达到了需要的效果。
对于 16 位数字执行此操作:
EvenNumber = (D1 & 0xFFFE);
68000 CPU 实际上有单独的位设置和位清除命令。在像您这样的情况下,显式清除操作数的位 0 而不返回布尔逻辑可能会更简单、更清晰:
bclr.l #0,d0
而不是
and.l $fffffffe,d0
你只需要清除底部位,所以当其他人使用长字指令时,使用 AND
的字节形式没有错
AND.B #0xFE, D1 ; make even
OR.B #0x01, D1 ; make odd
XOR.B #0x01, D1 ; toggle even/odd
无论 D1 中值的大小(字节、字或长字),您仍然清除了底部位并保持寄存器中所有其他位不变
或者
BCLR #0,D1 ; make even
BSET #0,D1 ; make odd
BCHG #0,D1 ; toggle even/odd
基本上如果我在 D1 中有一个数字,并且希望它始终是偶数,我如何确保它永远不会是奇数?
我知道和AND指令有关。但是当我尝试这样做时,它总是会减去 1。所以它会将奇数变为偶数,将偶数变为奇数。
基本上我该怎么做if n is odd, sub 1
奇数在二进制中以1
结尾,偶数在二进制中以0
结尾。您真正想要的是使最后一个二进制数字成为 0
,而不管它的开头是什么。 (这将从奇数中减去 1,并保持偶数不变。)
这样做的方法是与 1111...1110
进行与运算,其中除最后一位 0
外,所有二进制数字都是 1
。您可以通过对 0000...0001
进行按位求反来构造它,这当然只是 1
.
因此,如果您的号码是 n
,您想要计算 n & (~1)
。
and
您的电话号码 -2
。
在 2 的补码表示中,-2 是一个除最低位 (11111...110) 之外的所有位都设置为 1 的数字,因此,用作掩码时,它总是只删除数字的低位。这迫使它成为偶数(即使是负数也能正常工作)。
至于标题中的"viceversa":做相反的事情(=强制每个偶数到下一个奇数),只是or
和1
。这样就把低位设置为1,达到了需要的效果。
对于 16 位数字执行此操作:
EvenNumber = (D1 & 0xFFFE);
68000 CPU 实际上有单独的位设置和位清除命令。在像您这样的情况下,显式清除操作数的位 0 而不返回布尔逻辑可能会更简单、更清晰:
bclr.l #0,d0
而不是
and.l $fffffffe,d0
你只需要清除底部位,所以当其他人使用长字指令时,使用 AND
的字节形式没有错AND.B #0xFE, D1 ; make even
OR.B #0x01, D1 ; make odd
XOR.B #0x01, D1 ; toggle even/odd
无论 D1 中值的大小(字节、字或长字),您仍然清除了底部位并保持寄存器中所有其他位不变
或者
BCLR #0,D1 ; make even
BSET #0,D1 ; make odd
BCHG #0,D1 ; toggle even/odd