Getting Memory of variable

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
User avatar
James_Parsons
Posts: 67
Joined: 10 Jul 2013

Getting Memory of variable

Post by James_Parsons »

Hello world for a commodore PET

Code: Select all

CR    = $0D
out   = $FFD2

Main: 
        LDX #0
Print:
        LDA Msg, X
        BEQ Done
        JSR out
        INX
        BNE Print
Done:
        RTS

Msg:
        .byte "Hello, World!", CR, 0
How can I find the memory of the instruction

Code: Select all

.byte "Hello, World!", CR, 0
could I use the stack pointer I am trying to get a way to find the memory of the string
JMP $FFD2
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Getting Memory of variable

Post by GARTHWILSON »

In the listing you show, the first byte, the "H", would come immediately after the RTS. The program takes 14 bytes of code from label "Main" to label "Msg"; so let's say "Main" started at $300 for example, so the string would start at $30E.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Getting Memory of variable

Post by BigDumbDinosaur »

James_Parsons wrote:
Hello world for a commodore PET

Code: Select all

CR    = $0D
out   = $FFD2

Main: 
        LDX #0
Print:
        LDA Msg, X
        BEQ Done
        JSR out
        INX
        BNE Print
Done:
        RTS

Msg:
        .byte "Hello, World!", CR, 0
How can I find the memory of the instruction

Code: Select all

.byte "Hello, World!", CR, 0
could I use the stack pointer I am trying to get a way to find the memory of the string

I though you knew how to write x86 assembly language. The technique for getting the address (not "memory") of a string is a basic one to anybody who calls themselves an assembly language programmer. Here's some example code, written using MOS Technology standard syntax (understood by most Commodore 8 bit assemblers) that will work on any eight bit Commodore machine:

Code: Select all

bsout    =$ffd2                ;write to current device
zpptr    =$fa                  ;zero page pointer
;
;
;sprint: OUTPUT NULL-TERMINATED STRING
;
;        LDX #<STRING          ;string address LSB
;        LDY #>STRING          ;string address MSB
;        JSR SPRINT
;        BCS ERROR             ;address wrap
;
sprint   stx zpptr             ;save string address LSB
         sty zpptr+1           ;save string address MSB
         ldy #0                ;starting index
;
sprint01 lda (zpptr),y         ;get byte
         beq sprint02          ;end of string: done
;
         jsr bsout             ;send to current device
         iny                   ;bump index
         bne sprint01          ;get next
;
         inc zpptr+1           ;next page
         bne sprint01          ;continue
;
         sec                   ;address MSB wrapped
;
sprint02 rts                   ;return to caller
Salient points:

  1. If you are going to write a program on a specific machine, use the symbols that the manufacturer has assigned to ROM locations, not ones that you pull out of your hat. In the case of eight bit Commodore hardware, the "write character" ROM routine at $FFD2 is called BSOUT or CHROUT (I've leaned toward the former). The whole Commodore kernel jump table has similar names assigned. Using the official names makes it easier for others to decipher what you have written.
  2. It's best to use all lower case letters in non-quoted program text. I've run across a few assemblers that choke on mixed- or upper-case mnemonics and symbols. Run-on labels and symbols are best written as run_on_label_name, not RunOnLabelName. The latter is a very bad habit that developed in the Microsoft world and can be easy to misunderstand.
  3. The < and > modifiers to instruction operands, such as LDX #<STRING and LDY #>STRING, respectively load the least and most significant bytes of STRING's starting address. This is a common idiom in 6502 assembly language.
  4. Zero page addressing is commonly used for indirection. Hence the store instructions to ZPPTR at the beginning of the subroutine. Many 6502 instructions work only with zero page, which includes all indirect ones, except JuMP indirect.
  5. Comment your code!


There are more things to learn, of course, and I'm not about to start a "6502 assembly language for beginners" post. There are a lot of books to get you going. The 6502 is probably the most documented microprocessor ever developed. as far more of them have been used than almost any other type (a lot more than x86 MPUs). A search of 6502 in a search engine (I too recommend Ixquick) will turn up countless links.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
James_Parsons
Posts: 67
Joined: 10 Jul 2013

Re: Getting Memory of variable

Post by James_Parsons »

Really x86 assembly has turned into HLA this is an example for FASM

Code: Select all

include 'win64ax.inc' 

.code

  start:
	invoke	MessageBox,HWND_DESKTOP,"Hello, World!","Hello",MB_OK
	invoke	ExitProcess,0

.end start
its more of just a bunch of macro filled crap
JMP $FFD2
User avatar
enso
Posts: 904
Joined: 29 Sep 2012

Re: Getting Memory of variable

Post by enso »

Hardly high level. That example uses a very simple macro that defines some strings (using db), pushes pointers to them along with some constants, and calls MessageBox. There is nothing HLA about it, really.

You can write it in 'real' assembly like this

Code: Select all

string1: db "Hello, World",0
string2: db "Hello",0
start: push HWND_DESKTOP
  push string1
  push string2
  push MB_OK
  call MessageBox
  call ExitProcess
I may have the parameters backwards, but you get the idea. The macro is just to make your life easier, but no one is stopping you from just writing code.
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Getting Memory of variable

Post by GARTHWILSON »

Quote:
It's best to use all lower case letters in non-quoted program text. I've run across a few assemblers that choke on mixed- or upper-case mnemonics and symbols.
Really?! Wow, that sounds rather irresponsible on the part of the whoever wrote the assembler! WDC's Liechty & Eyes programming manual always has the mnemonics in all cap.s. I wouldn't particularly be in favor of requiring them to be in all cap.s, but I can't fathom not even allowing them to be.

In the first major programming project I was on at work (10,000 lines of assembly, in the late 1980's), we used lower-case for labels that were only of local interest, and cap.s for most everything else. (If we had the program-structure macros back then, most of the local labels would have been unnecessary.) With 80-column-screen limitation, even the comments had a ton of abbreviations and acronyms which don't go over well in lower-case. Now with the high-res monitor (even in DOS), I don't have to be so cryptic, and there's room to write comments in a more-friendly lower-case.

The Forths I've worked with used capitals for most things, and lower-case for internals that aren't usually accessed by the programmer once they're in place in the compiling words. So for example DO and LOOP are words that execute at compile time, and one of the things they do (besides some housekeeping and checking for compile-time errors) is to compile do and loop (lower-case). do and loop execute at run time. If you use the wrong case, you'll get something different from what you intended.

The ascenders and descenders of lower-case letters are part of what our brain uses to recognize words quickly when we read prose, when our eyes stop only once for every several words as we read hundreds of words per minute or more. Our process of reading code however is much different. When we read prose, the line divisions are mostly meaningless, existing primarily because an 8.5"x11" (or smaller) book is more manageable than a ribbon a mile long. However, the line breaks in program code are very significant, and ascenders and descenders blur those boundaries. (I know this is more an issue with higher-level languages than with assembly, since assembly only allows one instruction per line anyway.)

The numerals 0-9 are always "capitals." Why mix them with lower-case a-f in heX nUmBErS? A few systems won't recognize them in lower-case; so keeping them in upper-case should improve portability.

I realize some of this is a matter of preference that not everyone will agree with. I do like to promote good visual factoring and neatness though, for improving the chances that code will work right the first time, and making it more maintainable.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Getting Memory of variable

Post by BigDumbDinosaur »

GARTHWILSON wrote:
Quote:
It's best to use all lower case letters in non-quoted program text. I've run across a few assemblers that choke on mixed- or upper-case mnemonics and symbols.
Really?! Wow, that sounds rather irresponsible on the part of the whoever wrote the assembler! WDC's Liechty & Eyes programming manual always has the mnemonics in all cap.s. I wouldn't particularly be in favor of requiring them to be in all cap.s, but I can't fathom not even allowing them to be.

Way back when, some assemblers assumed that mnemonics were in lower case and would flag errors if, for example, STA was used in place of sta. It was brain-dead, to be sure. The very first 6502 assembler I used (in the 1970s) had this issue.

However, there are assemblers that do differentiate case when applied to symbols and will recognize FACA and Faca as two unique symbols, possibly opening the door to obdurate coding errors (the Kowalski simulator's assembler has this characteristic, but it can be defeated).

Quote:
The numerals 0-9 are always "capitals."

Technically speaking, from the standpoint of a computer, they are "unshifted," not "capitals," as SHIFTed numeral keys on just about all computer keyboards produce characters that have no relationship to numerals. This important difference was evident in the original form of ASCII from the 1960s, in which the codes <SI> (shift in, $0F) and <SO> (shift out, $0E) were defined (especially important when Tele-Types were involved).

Quote:
Why mix them with lower-case a-f in heX nUmBErS? A few systems won't recognize them in lower-case; so keeping them in upper-case should improve portability.

Mostly to avoid having to constantly use the [Shift] key when entering code. I do, however, use upper-case letters in hex numbers when mentioned in comments or prose. In actual code, including equates statements, I always use lower case to eliminate the constant use of the [Shift] key.

Quote:
I realize some of this is a matter of preference that not everyone will agree with. I do like to promote good visual factoring and neatness though, for improving the chances that code will work right the first time, and making it more maintainable.

I've generally stayed with lower case in program text because the readability for me has always been superior to upper case. In comments, I often upper-case acronyms (e.g., SCSI) to make them stand out from the text. However, I never upper-case labels, mnemonics or the letter characters in hex numbers when used in instructions. Why continually use the [Shift] key when it isn't necessary? I do upper-case commented examples in code sections, as I did in the above SPRINT exposition.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Getting Memory of variable

Post by GARTHWILSON »

I have to hit the <Shift> key of course for _ # $ * ( ) " etc. which is unavoidable either way; but otherwise generally use the cap.s lock for code and not for comments. That also helps visually separate code from comments.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Movax12
Posts: 16
Joined: 09 Nov 2012

Re: Getting Memory of variable

Post by Movax12 »

With ca65.

Hello world for a commodore PET

Code: Select all

[...]
Msg: .byte "Hello, World!", CR, 0

; display the value if Msg in hex..
.out .sprintf("Address of Msg:%04X", Msg)

If you don't want to refer to debug info. EDIT: Actually this probably won't work since the address won't be known until link. :(
Post Reply