Как я могу сделать бит сдвиг прямо в двоичном?

Надеюсь, это простой вопрос, но я не могу понять, как сделать двоичный сдвиг в двоичном коде. Это делается в среде LC3. Мне просто нужно знать, как арифметически делить на два и сдвигать вправо. Я знаю, что идти налево просто, просто добавив двоичное значение к себе, но я попробовал обратное для правого смещения битов (вычитание из себя, NOTing, а затем вычитание и т. Д. И т. Д.).

Или, если у вас есть лучший способ перевести x00A0 в x000A, это также было бы замечательно. Спасибо!

2 ответа

; right shift R0 1-bit with sign-extention
; Algorithm:    build bit form msb one by one
.ORIG   x3000
        AND     R1, R1, #0  ; r1 = 0
        ADD     R2, R1, #14 ; r2 = 14
        ADD     R0, R0, #0  ; r0 = r0
        BRzp    LOOP
        ADD     R1, R1, #-1 ; r1 = xffff
LOOP    ADD     R1, R1, R1  ; r1 << 1
        ADD     R0, R0, R0  ; r0 << 1
        BRzp    MSB0
        ADD     R1, R1, #1  ; r1++
MSB0    ADD     R2, R2, #-1 ; cnt--
        BRp     LOOP
        ADD     R0, R1, #0  ; r0 = r1
        HALT
.END
; right shift R0 1-bit with sign-extention
; Algorithm:    look-uo table and auto-stop
.ORIG   x3000
        AND     R1, R1, #0  ; r1 = 0
        LEA     R2, TABLE   ; r2 = table[]
        AND     R0, R0, #-2
LOOP    BRzp    MSB0
        LDR     R3, R2, #0  ; r3 = table[r2]
        ADD     R1, R1, R3  ; r1 += r3
MSB0    ADD     R2, R2, #1  ; r2++
        ADD     R0, R0, R0  ; r0 << 1
        BRnp    LOOP
        ADD     R0, R1, #0  ; r0 = r1
        HALT
TABLE
        .FILL   xC000
        .FILL   x2000
        .FILL   x1000
        .FILL   x0800
        .FILL   x0400
        .FILL   x0200
        .FILL   x0100
        .FILL   x0080
        .FILL   x0040
        .FILL   x0020
        .FILL   x0010
        .FILL   x0008
        .FILL   x0004
        .FILL   x0002
        .FILL   x0001
.END
.ORIG x3000
        BR      main
;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
;       UL7AAjr
;       shift right register R0
;       used rigisters R1, R2, R3, R4, R5
;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
shift_right
        AND     R4, R4, #0      ; R4 - counter = 15 times
        ADD     R4, R4, #15
        AND     R1, R1, #0      ; R1 - temp result
        LEA     R2, _sr_masks   ; R2 - masks pointer
_sr_loop
        LDR     R3, R2, #0      ; load mask into R3
        AND     R5, R0, R3      ; check bit in R0
        BRZ     _sr_zero        ; go sr_zero if bit is zero
        LDR     R3, R2, #1      ; R3 next mask index
        ADD     R1, R1, R3      ; add mask to temp result
_sr_zero
        ADD     R2, R2, #1      ; next mask address
        ADD     R4, R4, #-1     ; all bits done?
        BRNP    _sr_loop

        AND     R0, R0, #0      ; R0 = R1
        ADD     R0, R0, R1
        RET

_sr_masks
        .FILL   x8000
        .FILL   x4000
        .FILL   x2000
        .FILL   x1000
        .FILL   x0800
        .FILL   x0400
        .FILL   x0200
        .FILL   x0100
        .FILL   x0080
        .FILL   x0040
        .FILL   x0020
        .FILL   x0010
        .FILL   x0008
        .FILL   x0004
        .FILL   x0002
        .FILL   x0001
;»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
main
        LD      R0, data
        JSR     shift_right
        HALT

data   .FILL   xFFFF


.END
; right shift R0 1-bit with sign-extention
; Algorithm:    left-rotate 14 times with proper sign
.ORIG   x3000
        LD      R1, CNT
        ADD     R2, R0, #0
LOOP    ADD     R0, R0, R0  ; r0 << 1
        BRzp    NEXTBIT
        ADD     R0, R0, #1
NEXTBIT ADD     R1, R1, #-1
        BRp     LOOP
        LD      R3, MASK
        AND     R0, R0, R3
        ADD     R2, R2, #0
        BRzp    DONE
        NOT     R3, R3
        ADD     R0, R0, R3
DONE    HALT
MASK    .FILL   x3FFF
CNT     .FILL   14
.END

Это старый пост, но я столкнулся с той же проблемой, поэтому решил, что опубликую то, что нашел.

Когда вам нужно сделать сдвиг вправо, вы обычно делите двоичное число пополам (делите на 2), но это может быть проблемой в LC-3. Это код, который я написал, чтобы сместить бит вправо.

; Bit shift to the right
.ORIG x3000

MAIN
    LD R3, VALUE

    AND R5, R5, #0      ; Reseting our bit counter

    B_RIGHT_LOOP
        ADD R3, R3, #-2     ; Subtract 2 from the value stored in R3
        BRn BR_END      ; Exit the loop as soon as the number in R3 has gone negative 
        ADD R5, R5, #1      ; Add 1 to the bit counter
        BR B_RIGHT_LOOP     ; Start the loop over again 
    BR_END

    ST R5, ANSWER       ; Store the shifted value into the ANSWER variable

    HALT            ; Stop the program

; Variables
VALUE   .FILL x3BBC     ; Value is the number we want to do a bit-shift to the right
ANSWER  .FILL x0000

.END

Имейте в виду, что с этим кодом самый левый бит B[0] теряется. Также этот код не работает, если число, которое мы пытаемся сдвинуть вправо, отрицательно. Поэтому, если бит [15] установлен, этот код не будет работать. Пример:

VALUE .FILL x8000    ; binary value = 1000 0000 0000 0000
                     ; and values higher than x8000
                     ; won't work because their 15th
                     ; bit is set

Это должно по крайней мере заставить вас идти по правильному пути.

Другие вопросы по тегам