1

I prefer to code on my calculator in hex. I know my opcodes and what not, but i'm not sure how to create a string "hello" in register HL. Cany you help? I have googled it, but it's hard to find an answer because most people use compilers that handle that for them. I want to do this the hard and challenging way though. But I want the most efficient way of doing it in hex.

I tried....

[code here] C9 - RETURN [STRING HERE]

...but it doesn't seem LD has a way to get relative data. So I can't even get the address location after C9. Any tips?

AstroCB
  • 12,337
  • 20
  • 57
  • 73
John B
  • 23
  • 3
  • The usual way to do this sort of thing is to compile some code that does what you want, then look at what the compiler does. (There should be a way to ask the compiler to dump out the generated assembly code.) – Greg Hewgill Jan 29 '12 at 07:50
  • I would, but the compilers are all garbage and never work properly. – John B Jan 29 '12 at 08:17

3 Answers3

1

Does this help?

Strings

Strings are just lots of characters put together in consecutive order. However, it is important to identify the beginning/ends of strings. So, here's how it's done:

Null-Terminating Strings Strings that have a null term, or 0 at the end.

.DB "String Data",0

Pre-determined Length Strings Strings where the first byte is the length of the string.

.DB 11,"String Data"

As you are doing things with strings, this also looks useful for null terminated strings.

IanNorton
  • 7,145
  • 2
  • 25
  • 28
  • That doesn't help. I am not trying to do this in a asm compiler. I already know how to do that. I am doing this directly in hex on the calculator. That is why I need to know how to do it correctly. – John B Jan 29 '12 at 07:44
0

You can't store 5 ASCII characters ("hello") in a 2-byte register, which HL is. The only thing you can do is store these 5 characters somewhere in the memory and load HL with the address of this string (effectively, the address of its first character "h").

EDIT:

If you need to find the location of your subroutine while it's executing, you can read the return address from the stack and then minimally disassemble the instruction just before the return address.

If it's CALL (cc,) nn or JP (cc,) nn, the subroutine's address is encoded in the instruction's two last bytes.

If it's JP (HL/IX/IY), the address is in the register (HL, IX or IY) used for the indirect jump. To be able to recover this address, you'll have to save these registers' values in your subroutine (using e.g. PUSH).

If it's RET (cc), the address was on the stack when your subroutine started, but it may since have been overwritten by your routine's activities or that of the interrupt service routines. This is a tough case, but I hope it's not RET.

You can't disassemble the instruction blindly and reliably at the same time because different instructions have different lengths and what you may recognize as JP (HL) can in fact be just a part of a longer CALL nn. But the code that invokes your subroutine is unlikely to change and chances are there's only one place or one method of invocation, which means that once you know the instruction that's used to invoke your subroutine, you don't need to guess anything anymore, just write your code assuming it's always that instruction.

Using the above technique, you can use the layout you suggested in the question:

[code here] C9 - RETURN [STRING HERE]

You just need to recover the subroutine's address and add to it the subroutine's size. That'll be the address of the string.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • I know I can't store them into HL. But how would I store them into memory? I don't know what memory addresses are free to write to. I know I have to terminate the string with a 00 – John B Jan 29 '12 at 07:42
0

TI-83+/84+ I guess? Programs start at a fixed address, $9D95, so you can manually add the offset to that and use the absolute address.

harold
  • 61,398
  • 6
  • 86
  • 164