Reputation: 2618
I have to answer the following question about the 6502 assembly language:
"On the stack, there are the following values (top element first): 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
At address 0xc000
is the instruction jsr 0xABCD
. Which value will be stored in the program counter after the fetch/execute cycle and what will be the top element of the stack?"
I know that the program counter will be 0xABCD
, but I'm confused about the stack elements. I know that in the 6502 architecture, the stack grows from the top to the bottom (from 0x01FF
to 0x0100
). So, I assume, the stack pointer is pointing to the element 0x01
, right?
Now, the return address should be program counter + 3
, because there is the next
command, so I would say, 0xc003
will be pushed on the stack, but in little endian order, so c0
will be the top element. Is that correct?
Upvotes: 4
Views: 4032
Reputation: 1
I'm pretty sure that this is how it works:
First it takes the distance to the subroutine. If it's backwards, it puts it through a not gate. It then decrements and pushes that number to the stack, and moves up or down that far. When you want to return, it pulls from the stack, increments and moves back to the starting point and then continues the program.
For example:
jsr do_stuff
brk
do_stuff:
lda #$00
rts
First we jump forward 02
, and push 01
(02
- 1) to the stack. We then lda #$00
. When we rts
we pull 01
from the stack, add 1 to it (02
), then jump back that far. And now we exit.
Upvotes: -2
Reputation: 4664
Start with the S
register equal to $F9
, meaning everything after that in the $0100
page is the stack. Memory contents are as follows:
$01FA: 01 02 03 04 05 06
$ABCD: A6 23 LDX $23
; rest of the body of the subroutine
$AC03: 60 RTS
$C000: 20 CD AB JSR $ABCD
$C003: BD 40 06 LDA $0640,X
The JSR
instruction pushes the address of the last byte of the instruction. In this case, the address of the last byte is $C002
. The high byte is pushed first so that the low byte is in the lower address: push $C0
, then push $02
, then jump to $ABCD
. After this, the stack looks like this, with $C002
in little-endian byte order at the top, and S
has become $F7
.
$01F8: 02 C0 01 02 03 04 05 06
The subroutine at $ABCD
will end with the RTS
instruction, here shown at $AC03
. This instruction pulls the low and high bytes of the program counter. And then because the return address points at the last byte of the previous instruction, it adds 1. $C002
plus one is $C003
, the address of the first byte of the next instruction in the caller.
Upvotes: 9
Reputation: 71576
I believe what happens on a jsr is
stack[stack_pointer] = return_high
stack_pointer--
stack[stack_pointer] = return_low
stack_pointer--
pc = jsr address
so if you are claiming that your stack pointer is pointing at the 0x01 and 0x02 is a lower/smaller address then 0x01 and 0x02 will be overwritten and when you hit your subroutine the stack will be pointing at 0x03.
Upvotes: 1