0

How I can use a value that has been stored into a register after N lines of code? For example I want to use the value that has been stored into bc later in INIT. I tried with push and pop but after the cp 2 instruction the program won't jump to INIT2.

    ld bc, 2
    push bc

...

INIT:
     pop bc
     cp 2
     jp z, INIT2


gameloverr
  • 53
  • 1
  • 8
  • 2
    It might help to read [mcve]. You don't show the rest of your code, so I have to guess that you did something else in between that changed the stack, like pushing another value or popping the value into another register. – Dave S Dec 28 '19 at 19:49
  • 6
    I can't really tell what you are trying to achieve,but it might help to know that `cp ` only works with the 8-bit `A` register. If you are trying to compare `BC` to 2, you'll need to check that `B` (the upper 8 bits of BC) is 0 and `C` (the lower 8 bits of BC) is 2. There are clever tricks to do this, but the easy way (if you aren't used to Z80) is a crude, `ld a,b \ cp 0 \ jr nz,ne2 \ ld a,c \ cp 2 \ jr z,INIT2`. – Zeda Dec 29 '19 at 03:26

2 Answers2

1

Values can be stored in three places:

  1. a register
  2. a memory address
  3. a port

When using the stack you are simply putting the value of a register pair in (push), or loading the value of a register pair from (pop), an address in memory pointed to by the stack pointer (sp). Since the stack is just memory, the meaning of any value is arbitray, you will need to balance your pop and push to pop the value you intended - only you know what is actually on the stack.

An easier and less error prone approach - albeit slower - is to dedicate some memory to storing your value:

var.counter: defw 0

...

    ld bc,2
    ld (var.counter),bc

...

INIT:
     ld bc,(var.counter)
     cp 2
     jp z, INIT2

Sometimes (if you are executing in RAM) limited self modifying code can be effective:

    ld bc,2
    ld (smc.counter+1),bc

...

INIT:
smc.counter:
     ld bc,0
     cp 2
     jp z, INIT2

And as mentioned in the comments to your question cp compares the value with the accumulator (register a) and not register pair bc.

Stefan Drissen
  • 3,266
  • 1
  • 13
  • 21
0

You've almost got it right: CP compares the A register, so you'd need to get your value back into the A register:

LD   B, 2
PUSH BC
...
POP  AF
CP   2
JP   Z, INIT2

Since PUSH and POP work on register pairs only, you have no option of pushing/popping a single byte. Instead, we push BC, with C value being whatever it happens to be. Then when we pop AF, the flags get set to some random value that C had, but it doesn't matter since CP overwrites them anyway.

If you wanted to store a 16-bit value, and then do a 16-bit comparison, you would do it as follows:

LD   BC, 1234
PUSH BC
...
POP  BC
SCF
LD   HL, 1234-1 ; value to compare with - 1
SBC  HL, BC     ; Z is set when BC was equal to 1234
JP   Z, INIT2 
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313