gameloverr
gameloverr

Reputation: 63

Z80 assembly push and pop a value

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


Upvotes: 0

Views: 1886

Answers (2)

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 

Upvotes: 0

Stefan Drissen
Stefan Drissen

Reputation: 3374

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.

Upvotes: 1

Related Questions