【发布时间】:2019-06-25 23:12:33
【问题描述】:
所以我正在从事 nand2tetris 项目,我想在软件级别实现右移逻辑,因为硬件不支持它。
我知道右移逻辑是除以二。所以我第一次实现它时会计算在值变为 0 或负数之前我能够从初始值中减去 2 的次数。如果数字为负数,则类似。
但是,我发现它不起作用的情况。我想右移-27139。那么移位后的二进制值是19199。应该是19198。所以我正在寻找一种新的方式来实现移位。
我可以使用and 值、or 值、add 和 subtract,这就是我可以使用的全部内容。
OSFTW
这是我在 Hack 实现的汇编语言中的代码:
//============================================================
// SLR: Shift Logical Right (by 1)
//============================================================
(SLR)
@SLR.1 // Load value
D=M
@SLR.2
M=0 // Clear variables
@SLR_POSITIVE_LOOP // If value is positive, go to the positive loop
D;JGT
(SLR_NEGATIVE_LOOP)
@SLR.1 // Add 2 to value, since it's negative
M=M+1
M=M+1
@SLR.1 // If initial value was negative and current value is positive or zero, jump out of loop
D=M
@SLR_NEG
D; JGE
@SLR.2 // If value is negative, add 1 to SLR.2 (we're dividing)
M=M+1
@SLR.1 // If value is less than 0, restart the loop
D=M
@SLR_NEGATIVE_LOOP
D; JLT
(SLR_NEG)
@SLR.2
D=M
D=!D // Invert the result
D=D+1 // Add 1 to finish converting
@32767 // And it with 0111111111111111 to clear the sign bit
D=D&A
@SLR.2
M=D // Set value
@SLR_END // Jump to end of loop
0;JMP
(SLR_POSITIVE_LOOP)
@SLR.1 // Subtract 2 from value
M=M-1
M=M-1
@SLR.1 // If initial value was positive and current value is negative or zero, jump out of loop
D=M
@SLR_END
D; JLE
@SLR.2 // If value is still positive, add 1 to SLR.2 (we're dividing)
M=M+1
@SLR.1 // If value is greater than 0, restart the loop
D=M
@SLR_POSITIVE_LOOP
D; JGT
(SLR_END) // Loop is over. Set value of SLR.1 to that of SLR.2, for return purposes
@SLR.2 // Place result in correct place
D=M
@SLR.1
M=D
@SLR.0 // Return to calling function
A = M
0; JMP
【问题讨论】:
-
如果你把一个奇数减去 2 那么它总是奇数,所以结果。另外,反复减去也不是一个好的解决方案,因为它会导致程序循环数千次pan>
-
重复地将有符号数减去 2 就像算术移位一样,因为符号位总是复制到结果 (-27139 - 2 = -27137),结果向 -Inf 舍入。这就是你看到结果的原因。要将零移入,请执行无符号减法 ((unsigned)-27139 - 2 =38397 - 2 = 38395)
-
右移然后修复 msbit 以匹配下一个 msbit。少得多的工作快得多。如果这是一个无符号数,那么您根本不必这样做,只需向右移动,即除以 2。
-
类似问题here
-
如果是正数,就是除以二。
标签: assembly bit-manipulation bit-shift nand2tetris