Assembly 实现逻辑右移

Assembly 实现逻辑右移,assembly,bit-manipulation,bit-shift,nand2tetris,Assembly,Bit Manipulation,Bit Shift,Nand2tetris,因此,我正在从事NAND2TTERIS项目,我想在软件级别实现右移逻辑,因为硬件不支持它 我知道右移逻辑是二除。因此,我第一次尝试实现它时,会计算在值变为0或负值之前,我能够从初始值中减去2的次数。如果数字为负数,则类似 但是,我发现了一个不起作用的场景。我想右转-27139。移位后的二进制值是19199。应该是19198年。因此,我正在寻找一种新的方式来实现这一转变 我可以和值,或值,加和减,这就是我可以支配的全部 OSFTW 以下是我在Hack实现的汇编语言中的代码: //=========

因此,我正在从事NAND2TTERIS项目,我想在软件级别实现右移逻辑,因为硬件不支持它

我知道右移逻辑是二除。因此,我第一次尝试实现它时,会计算在值变为0或负值之前,我能够从初始值中减去2的次数。如果数字为负数,则类似

但是,我发现了一个不起作用的场景。我想右转-27139。移位后的二进制值是19199。应该是19198年。因此,我正在寻找一种新的方式来实现这一转变

我可以
值,
值,
,这就是我可以支配的全部

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,直到结果小于2,这时减法的次数就是你的商(即右移值)

C语言中的一个示例实现:

int lsr(int valueToShift)
{
    int shifted = 0;
    uint16_t u = valueToShift;

    while (u >= 2) {
        u -= 2;
        shifted++;
    }

    return shifted;
}

如果将要移位的值视为无符号,则会变得更容易,因为逻辑右移不会保留符号。然后你只需重复减去2,直到结果小于2,这时减法的次数就是你的商(即右移值)

C语言中的一个示例实现:

int lsr(int valueToShift)
{
    int shifted = 0;
    uint16_t u = valueToShift;

    while (u >= 2) {
        u -= 2;
        shifted++;
    }

    return shifted;
}

如果将要移位的值视为无符号,则会变得更容易,因为逻辑右移不会保留符号。然后你只需重复减去2,直到结果小于2,这时减法的次数就是你的商(即右移值)

C语言中的一个示例实现:

int lsr(int valueToShift)
{
    int shifted = 0;
    uint16_t u = valueToShift;

    while (u >= 2) {
        u -= 2;
        shifted++;
    }

    return shifted;
}

如果将要移位的值视为无符号,则会变得更容易,因为逻辑右移不会保留符号。然后你只需重复减去2,直到结果小于2,这时减法的次数就是你的商(即右移值)

C语言中的一个示例实现:

int lsr(int valueToShift)
{
    int shifted = 0;
    uint16_t u = valueToShift;

    while (u >= 2) {
        u -= 2;
        shifted++;
    }

    return shifted;
}

您应该使用二进制或十六进制,因为使用十进制很难想象数字的表示形式

如果您有算术移位,但没有逻辑移位,最明显的解决方案是清除顶部位(如果是负数)

int逻辑右移(int x,int移位)
{

return(x>>shift)&((1U>shift)&(~(~0)您应该使用二进制或十六进制,因为使用十进制很难想象数字的表示形式

如果您有算术移位,但没有逻辑移位,最明显的解决方案是清除顶部位(如果是负数)

int逻辑右移(int x,int移位)
{

return(x>>shift)&((1U>shift)&(~(~0)您应该使用二进制或十六进制,因为使用十进制很难想象数字的表示形式

如果您有算术移位,但没有逻辑移位,最明显的解决方案是清除顶部位(如果是负数)

int逻辑右移(int x,int移位)
{

return(x>>shift)&((1U>shift)&(~(~0)您应该使用二进制或十六进制,因为使用十进制很难想象数字的表示形式

如果您有算术移位,但没有逻辑移位,最明显的解决方案是清除顶部位(如果是负数)

int逻辑右移(int x,int移位)
{

返回(x>>shift)和((1U>shift)和((~0)更快的方法可能是使用加法。例如:

uint32\t LSR(uint32\t值,整数计数){
uint32_t结果=0;
uint32温度;
而(计数<32){
温度=值+值;
如果(temp
基本思想是将64位无符号整数左移“32计数”次,然后返回最高32位


在汇编中,上面的大多数代码(分支等)可能会变成类似于
add value,value
然后
add\u with\u carry result,result
一种更快的方法可能是使用加法。例如:

uint32\t LSR(uint32\t值,整数计数){
uint32_t结果=0;
uint32温度;
而(计数<32){
温度=值+值;
如果(temp
基本思想是将64位无符号整数左移“32计数”次,然后返回最高32位


在汇编中,上面的大多数代码(分支等)可能会变成类似于
add value,value
然后
add\u with\u carry result,result
一种更快的方法可能是使用加法。例如:

uint32\t LSR(uint32\t值,整数计数){
uint32_t结果=0;
uint32温度;
而(计数<32){
温度=值+值;
如果(temp
基本思想是将64位无符号整数左移“32计数”次,然后返回最高32位


在汇编中,上面的大多数代码(分支等)可能会变成类似于
add value,value
然后
add\u with\u carry result,result
一种更快的方法可能是使用加法。例如:

uint32\t LSR(uint32\t值,整数计数){
uint32\t结果=