Example , left shifting 1 bit from location 1900H and store in location 1901H , and empty bit positions are filled with zero
How to shift the contents of a memory location left 1 bit to another memory using z80 assembly language
635 views Asked by 谢RenS AtThere are 2 answers
Let's start with the simpler case of shifting one byte left, and
shifting in a 0-bit. On the Z80, this perfectly describe the
sla
set of instructions:
sla [reg8]
Where reg8
is one of the registers A/B/C/D/E/H/L, or (HL), or (IX+d)
or (IY+d). The top bit gets shifted out of the register (or
memory location in the case of (HL)/(IX+d)/(IY+d)) and into the
carry flag.
There is a well known trick for 4 special cases on the Z80.
Since shifting left (while shifting in a 0) is the same as
multiplying by 2, you can actually simulate an sla
with:
add a,a ; replaces `sla a`, save 1 byte, 4cc
add hl,hl ; replaces `sla l \ rl h`, save 3 bytes, 5cc
add ix,ix ; (to my knowedge, this is the only "legal" way to shift the IX register pair like this)
add iy,iy ; (same with IY)
These are faster and smaller and almost always the best replacement.
In any event, the bit that was shifted out is now in the carry
flag, so you can shift that into the next byte using the rl
class of instructions:
rl [reg8] ;2 bytes, 8 clock cycles
rla ;1b, 4cc. Basically a fast `rl a` but affects fewer flags.
Notice that the Z80 has an optimized ersion of this specifically for the A register.
Now on to your question: There are many ways to do this on the Z80. If you know precisely where in memory the bytes are, @tum_ provided the fastests and smallest option:
ld hl,(1900H) ; Read the two bytes into HL
add hl,hl ; Shift left
ld (1900H),hl ; Store HL back to the bytes.
This takes advantage of the sla
trick from earlier, where you
can just add HL to itself (HL*2) to shift it left. However, if
the bytes are not at a pre-determined location, but HL points to
the bytes, then:
sla (hl) ; `sla` the byte at HL
inc hl ; Advance to the next byte
rl (hl) ; `rl` the byte at HL
You can also do it a little slower (not recommened, just showing this for educational purposes):
ld a,(hl) ; read the byte at HL into A
add a,a ; `sla a`, but faster and smaller
ld (hl),a ; Store it back to the byte at HL
inc hl ; advance to the next byte
ld a,(hl) ; read the byte at HL into A
rla ; `rl a`, but faster and smaller
ld (hl),a ; Store it back to the byte at HL
This is a lot of info, but hopefully this helps!
Home work?
Not 100% sure if this is what you're asking for, but anyway:
There are, of course, other ways to achieve the same.
Added another one from the comment:
The above snippet is 7 bytes in size and, probably, the shortest possible code for the task.