Jump to content

Bitwise operations: Difference between revisions

→‎{{header|68000 Assembly}}: also revised 6502 example
(→‎{{header|68000 Assembly}}: also revised 6502 example)
Line 136:
</pre>
=={{header|6502 Assembly}}==
Bitwise operations are done using the accumulator and an immediate constant (prefixed with #) or a value at a specified memory location (no #.)
Integer one is in the accumulator, integer two is in zero page memory location "temp". Both are considered to be unsigned.
<lang 6502asm>AND temp ;ANDs accumulator with temp.
 
<lang 6502asm>LDA #$05
OR temp ;ORs accumulator with temp.
STA temp ;temp equals 5 for the following</lang>
 
;AND
EOR temp ;XORs accumulator with temp.
<lang 6502asm>LDA #$08
AND temp</lang>
 
;OR
EOR #$FF ;bitwise NOT on the accumulator.</lang>
<lang 6502asm>LDA #$08
ORA temp</lang>
 
;XOR
The 6502 can only shift left or right by one. Shifting by a variable number requires a loop.
<lang 6502asm>LDA #$08
There is also no arithmetic shift right on the 6502, only logical. It can also be replicated with a few commands.
EOR temp</lang>
 
;NOT
<lang 6502asm>multi_ASL:
<lang 6502asm>LDA #$08
LDX temp
EOR 255</lang>
CPX #$08
BNE loop_ASL
;although this is called "ASL" the name is misleading because it doesn't preserve the sign of bit 7!
;value will be zero anyway so don't bother
LDA #0
RTS
 
The 6502 doesn't have arithmetic shift right, but it can be replicated, provided the negative flag is set according to the value in the accumulator.
loop_ASL:
<lang 6502asm> LDA #$FF
ASL
CLC ;clear the carry. That way, ROR will not accidentally shift a 1 into the top bit of a positive number
DEX
BPL loop_ASLSKIP
SEC ;if the value in A is negative, setting the carry will ensure that ROR will insert a 1 into bit 7 of A upon rotating.
RTS
SKIP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ROR</lang>
multi_LSR:
LDX temp
CPX #$08
BNE loop_LSR
;value will be zero anyway so don't bother
LDA #0
RTS
 
The 6502 can only rotate a value by one, not an arbitrary number. A looping routine is needed for rotates larger than 1.
loop_LSR:
Also, the 6502's <code>ROL</code> and <code>ROR</code> rotate instructions both rotate through the carry, unlike the instructions on other architectures with the same name. (68000, x86, and ARM all have a "ROR" command but it doesn't rotate through the carry on those CPUs.)
LSR
<lang 6502asm>LDA #$01
DEX
ROL ;if the carry was set prior to the ROL, A = 3. If the carry was clear, A = 2.</lang>
BPL loop_LSR
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
multi_ASR
LDX temp
CPX #$08
BNE loop_ASR
;value will be either 0 or #$FF anyway so don't bother
PHA
PLA ;set the flags according to the accumulator
 
<lang 6502asm>LDA #$01
BMI returnFF
ROR ;if the carry was set prior to the ROR, A = 0x80. If clear, A = 0.</lang>
LDA #0
RTS
returnFF:
LDA #$FF
RTS
 
loop_ASR:
jsr ASR
DEX
BPL loop_ASR
RTS
 
=={{header|68000 Assembly}}==
ASR:
Like with most 68000 commands, you can specify a length parameter. Anything outside that length is unaffected by the operation.
CLC ;clear the carry
;AND
PHA
<lang 68000devpac>MOVE.W D0,#$100
PLA ;sets flags according to accumulator
MOVE.W D1,#$200
BPL skip
AND.W D0,D1</lang>
SEC ;set the carry, the carry rotates into bit 7 during the ROR
 
skip:
;OR
ROR ;top bit will be the same as it was before.
<lang 68000devpac>MOVE.W D0,#$100
RTS
MOVE.W D1,#$200
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OR.W D0,D1</lang>
multi_ROL:
 
LDX temp
;XOR
loop_ROL:
<lang 68000devpac>MOVE.W D0,#$100
ROL
MOVE.W D1,#$200
DEX
EOR.W D0,D1</lang>
BPL loop_ROL
 
RTS
;NOT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
<lang 68000devpac>MOVE.W D0,#$100
multi_ROR:
NOT.W D1</lang>
LDX temp
 
loop_ROR:
;Left Shift
ROR
<lang 68000devpac>MOVE.W D0,#$FF
DEX
MOVE.W D1,#$04
BPL loop_ROR
LSL.W D0,D1 ;shifts 0x00FF left 4 bits</lang>
RTS</lang>
 
;Right Shift
<lang 68000devpac>MOVE.W D0,#$FF
MOVE.W D1,#$04
LSR.W D0,D1 ;shifts 0x00FF right 4 bits</lang>
 
;Arithmetic Right Shift
<lang 68000devpac>MOVE.W D0,#$FF00
MOVE.W D1,#$04
ASR.W D0,D1 ;shifts 0xFF00 right 4 bits, preserving its sign</lang>
 
;Left Rotate
<lang 68000devpac>MOVE.W D0,#$FF00
MOVE.W D1,#$04
ROL.W D0,D1</lang>
 
;Right Rotate
<lang 68000devpac>MOVE.W D0,#$FF00
MOVE.W D1,#$04
ROR.W D0,D1</lang>
 
;Left Rotate Through Extend Flag
<lang 68000devpac>MOVE.W D0,#$FF00
MOVE.W D1,#$04
ROXL.W D0,D1</lang>
 
;Right Rotate Through Extend Flag
<lang 68000devpac>MOVE.W D0,#$FF00
MOVE.W D1,#$04
ROXR.W D0,D1</lang>
 
=={{header|8051 Assembly}}==
1,489

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.