Disassembler-friendly constant parameter to routine
Posted: Sun Feb 24, 2008 5:08 am
I write lots of test programs that are run on hardware and emulators to be sure they both have the same behavior. People often step through them with a debugger in emulators, so I'd like them to be relatively easy to disassemble. I have a few routines that take constant parameters and preserve all registers (so they can be inserted anywhere without worrying about stomping on anything). Putting the value/address into registers means I have to save and restore them, which becomes too bloated, especially since this is for the NMOS 6502 which lacks PHX, PHY, etc. As an example, I'll use a print_string routine that takes a zero-terminates ASCII string. The following are the various approaches I've come up with. I'm only focusing on the caller, since that's what matters most.
The details are of course encapsulated in a macro, so the user code just contains the following:
print_string "Test"
Any other ideas for making it play well with a disassembler?
Code: Select all
.zeropage
addr: .res 2
.rodata
test: .byte "Test",0
.code
; The most straight-forward way, but it's bloated
pha
tya
pha
lda #<test
ldy #>test
jsr print_string
pla
tay
pla
; More compact and still very clean. I might go with this.
pha
lda #<test
sta addr
lda #>test
jsr print_string
pla
; Will confuse a disassembler since it will interpret the string
; as instructions and could easily "munch" the next instruction.
; The return addr is used to find the string data, then execution
; resumes just after the zero terminator.
jsr print_string
.byte "Test",0
; Also involves return address examination, but doesn't confuse
; disassembler/debugger. Still more complex to implement.
; The return addr is used to find the address inside the BIT
; instruction. The point of using BIT is that it only modifies
; flags, and we don't have to adjust the return address either,
; just read it.
jsr print_string
bit test
; Simpler to implement, since nested return addr would be popped off
; and never returned to. Main problem is then that each string
; printed turns into a JSR to a different address in the main code.
jsr print_test
...
print_test:
jsr print_string
.byte "Test",0print_string "Test"
Any other ideas for making it play well with a disassembler?