Confused by Example ASM Program

Programming the 6502 microprocessor and its relatives in assembly and other languages.
load81
Posts: 71
Joined: 16 Nov 2018

Re: Confused by Example ASM Program

Post by load81 »

BitWise wrote:
It can even be structured...
...
which removes the need for labels.
Wow, this feedback is great all the way around.

Damn, BitWise, you rather neatly cleaned that up that code with assembler directives. Sorry for the delay in my reply. I don't always get email notifications when someone post a response.
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Confused by Example ASM Program

Post by BigDumbDinosaur »

load81 wrote:
BitWise wrote:
It can even be structured...
...
which removes the need for labels.
Wow, this feedback is great all the way around.

Damn, BitWise, you rather neatly cleaned that up that code with assembler directives. Sorry for the delay in my reply. I don't always get email notifications when someone post a response.
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.

That said, an experienced assembly language programmer can see "structure" in what appears to be alien mumbo-jumbo to programmers who don't know assembly language. The use of macros can help in this regard, as they can be used to substitute English-like statements for complex sequences of assembly language instructions, especially ones that manipulate complicated data structures. I constantly use macros to reduce the tedium of writing large programs, and also as a defensive mechanism against insidious bugs that come from typos or simple character transposition errors, e.g., TXA when what was meant was TAX.

As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen. A very useful tool for that purpose is the Kowalski 6502 simulator, which is a complete development environment, plus a simulator in which to try out your programs. You ought to take a look at it.
Last edited by BigDumbDinosaur on Wed Apr 29, 2020 7:48 am, edited 1 time in total.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Confused by Example ASM Program

Post by BigEd »

> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Confused by Example ASM Program

Post by JimBoyd »

cjs wrote:
The negative and carry flags will be set as appropriate as well, but the result will be thrown away, rather than being stored somewhere.
Each flag is preserved until an instruction is executed which affects that particular flag. For example, if there is an instruction which sets the carry flag followed by several instructions which don't affect the carry flag, the carry flag will still be set and available for a branch on carry set ( BCS ).
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Confused by Example ASM Program

Post by BigDumbDinosaur »

BigEd wrote:
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!
That's assuming, of course, the programmer commented his code. I've seen a lot of assembly language source in which a comment would die from loneliness. :D It can be tough going for a novice to try to decipher what such code does.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Confused by Example ASM Program

Post by BigEd »

BigDumbDinosaur wrote:
BigEd wrote:
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!
That's assuming, of course, the programmer commented his code. I've seen a lot of assembly language source in which a comment would die from loneliness. :D It can be tough going for a novice to try to decipher what such code does.
Even so, even so: code that's written to do something useful can be worth trying to puzzle out. Not every puzzle comes with hints, and not every puzzle would be better if it did.
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Confused by Example ASM Program

Post by cjs »

JimBoyd wrote:
cjs wrote:
The negative and carry flags will be set as appropriate as well, but the result will be thrown away, rather than being stored somewhere.
Each flag is preserved until an instruction is executed which affects that particular flag.
Right. But the (numerical) result of the subtraction done by CMP is thrown away; only the flags are kept.
Curt J. Sampson - github.com/0cjs
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: Confused by Example ASM Program

Post by JimBoyd »

cjs wrote:
JimBoyd wrote:
cjs wrote:
The negative and carry flags will be set as appropriate as well, but the result will be thrown away, rather than being stored somewhere.
Each flag is preserved until an instruction is executed which affects that particular flag.
Right. But the (numerical) result of the subtraction done by CMP is thrown away; only the flags are kept.
Oops. For some reason I wasn't thinking about the numerical result, just the resulting flags.
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Confused by Example ASM Program

Post by BillG »

BigEd wrote:
BigDumbDinosaur wrote:
BigEd wrote:
> As is the case with other programming languages, you develop skill in assembly language by writing source code, assembling it and running your program to see what does or doesn't happen

Also by reading code!
That's assuming, of course, the programmer commented his code. I've seen a lot of assembly language source in which a comment would die from loneliness. :D It can be tough going for a novice to try to decipher what such code does.
Even so, even so: code that's written to do something useful can be worth trying to puzzle out. Not every puzzle comes with hints, and not every puzzle would be better if it did.
Reverse engineering usually involves disassembling code, then figuring out what it does. It is not uncommon to hear of working with poorly commented code described as "reverse engineering." A good programmer will document things as they are understood instead of leaving the code unchanged.

A comment such as

Code: Select all

    dex    ; Decrement X register
adds no useful information and may as well not be there.

A comment like

Code: Select all

    dex    ; Decrement loop counter
is generally not much better as the structure of a loop is usually obvious.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Confused by Example ASM Program

Post by barrym95838 »

My current reverse engineering obsession is WOZ BASIC. I found a few very-lightly commented sources on the 'net, and I am now wading in neck-deep with the goal of figuring out exactly what WOZ was doing throughout that originally hand-assembled ~6K ball of twine. If it somehow magically becomes one of my few projects that reaches a satisfactory conclusion, I'll post my commented source on 6502.org and open a discussion for a strategy involving the addition of a few features notably absent, like DATA, READ, RESTORE, CHR$ ... and the feature that WOZ had wanted to add if he hadn't been so busy at the time ... WOZ floats!
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
load81
Posts: 71
Joined: 16 Nov 2018

Re: Confused by Example ASM Program

Post by load81 »

BigDumbDinosaur wrote:
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.
Hmmm.... So, what is your take on projects like High Level Assembly (HLA)?
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Confused by Example ASM Program

Post by BillG »

barrym95838 wrote:
My current reverse engineering obsession is WOZ BASIC. I found a few very-lightly commented sources on the 'net, and I am now wading in neck-deep with the goal of figuring out exactly what WOZ was doing throughout that originally hand-assembled ~6K ball of twine.
Me too. The source code I have for the TSC FLEX BASIC interpreter is not exactly well documented. I will have to more or less understand it in order to build a 6502 version.

Then there is their Extended BASIC. No source code for it that I can find, so building that will require extreme reverse engineering.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Confused by Example ASM Program

Post by GARTHWILSON »

Quote:
load81 wrote:
BigDumbDinosaur wrote:
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.
Hmmm.... So, what is your take on projects like High Level Assembly (HLA)?

That's why he went on to say,
Quote:
The use of macros can help in this regard, as they can be used to substitute English-like statements for complex sequences of assembly language instructions, especially ones that manipulate complicated data structures

I have an article on that at http://wilsonminesco.com/StructureMacros/, with extended programming examples in the last 40% of the page at http://wilsonminesco.com/multitask/, and more on how the program flow-control macros work internally in section 17 of the 6502 stacks treatise at http://wilsonminesco.com/stacks/pgmstruc.html . On that last page's last example, you can mouse-over the underlined words to see an explanation of what what that line does. The code hardly looks like assembly language.
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: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Confused by Example ASM Program

Post by BigDumbDinosaur »

load81 wrote:
BigDumbDinosaur wrote:
It's important to understand that raw assembly language has no structure. That is one of the reasons why use of assembly language in most aspects of computing has greatly diminished.
Hmmm.... So, what is your take on projects like High Level Assembly (HLA)?
It's nothing about which I could get excited. Randall Hyde has great credentials, has written a fine book about assembly language and all that, but I think is a bit misguided with this concept.

The very name "high level assembly" is an oxymoron. Assembly language is, by definition, the lowest level at which you can program a computer, short of manually poking bytes into RAM with a panel of switches and push buttons. As soon as you are insulated from the assembler, which is what "high level assembly" is doing, you are no longer programming in assembly language. If you want that much insulation you might as well fire up a COBOL compiler or a BASIC interpreter.

Programs are written in assembly language so as to avoid the performance issues that are present to some extent in all high level languages, compiled or interpreted. Also, sometimes assembly language is the only way to accomplish something, or to accomplish something in an efficient manner, especially on small 8- and 16-bit systems such as what we build.

To quote that Wikipedia article:
Quote:
It uses a syntax loosely based on several high-level programming languages (HLLs), such as Pascal, Ada, Modula-2, and C++, to allow creating readable assembly language programs, and to allow HLL programmers to learn HLA as fast as possible.
That doesn't sound like assembly language to me. Instead, it sounds like illustrating a landscape by connecting the dots. Just what is it someone would learn from a mish-mash of Pascal, Ada (the ultimate designed-by-a-committee programming language), etc? And don't get me started on C++, what I consider to be the ultimate bloatware language.

As for "creating readable assembly language programs," there's this little thing called a comment, which if judiciously used in assembly language source code, makes the program eminently readable. Good commenting is the heart of writing understandable programs in any language. If the programmer can't explain in his/her comments what the program is doing then he/she doesn't know what it's doing. Perhaps Mr. Hyde should hammer that home to his followers.

Both Garth and I strongly advocate for the use of macros in assembly language programs, especially large programs. Macros allow you to add some higher-level features to your programs without sacrificing the inherent speed and flexibility of assembly language. A well-chosen macro name can make for very readable code. Macros can also be invaluable for reducing errors, as a properly-structured macro will report an assembly time error that might go undetected in raw assembly language (e.g., missing parameters).

That said, nothing can beat the performance of assembly language that has been hand-optimized to produce the tightest loops and smallest code. You can't do that when the language does all sorts of hand-holding for you. The folks who developed action games for machines like the Commodore 64 understood that 37 years ago. It's still true today.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Confused by Example ASM Program

Post by cjs »

BillG wrote:
A good programmer will document things as they are understood instead of leaving the code unchanged.
Or even rewrite the code as he goes. That's a technique I often use when when trying to understand new code. Whether I keep the rewritten code or just throw it out depends on how good the test framework is, whether I actually improved it or not, and so on, but the mere act of trying to do what was already done in a different way can be very enlightening.
Quote:
A comment such as

Code: Select all

    dex    ; Decrement X register
adds no useful information and may as well not be there.
In fact, it may have negative value: making a developer read a lot of useless (to her) verbiage can slow her down.

But on the other hand, even comments like the above may be valuable. The key is to understand your audience: who will be reading your code, and what do they likely need to understand it? If you're writing code you expect to be read mainly by people entirely unfamiliar with 6502 assembly language, a comment like the above might be exactly the right thing.

For example, here's a little routine with a fair amount of subtlety in it:

Code: Select all

;   Convert ASCII character to binary number in bases up to 41.
;   This translates A-Z[\]^_ and a-z{|}~DEL as 10, 11...40.
;   The caller must check the returned value if the intended base was
;   less than 41.
;
;          A: (written) ASCII character to convert; binary number on return
;     N flag: (written) clear on success, set on error.
;       X, Y: (preserved)
;
convascdigit
            cmp #'9'+1
            bcs .letter         ; >'9', convert letter
            sbc #'0'-1          ; convert digit; if <'0', N flag set for error
            rts                 ; N clear, no error
.letter
            and #%11011111      ; clear bit 5 to convert to upper-case
            bmi .exit           ; high bit set, error
            sbc #'A'-$0A
            cmp #$0A            ; if <$0A, set N flag to indicate error
.exit       rts
That version is what I'd normally use in my projects, or post here if I were seeking help or comments on it. But this code is also the example I use for explaining certain aspects of assembly language to people, such as careful use and tracking of flag values. So the the actual source code is in fact a bloated 50-line monstrosity where you can hardly find the code amongst the comments. It's pretty horrible to read if you're a half-way decent 6502 programmer, but good for beginners, and doesn't really hurt the project too much since it's unlikely to be changed in the future anyway.

Code: Select all

;   Convert ASCII character to binary number in bases up to 41.
;   This translates A-Z[\]^_ and a-z{|}~DEL as 10, 11...40.
;   The caller must check the returned value if the intended base was
;   less than 41.
;
;          A: (w) ASCII character to convert; binary number on return
;     N flag: (w) clear on success, set on error.
;       X, Y: (p)
;
convascdigit
            ;   This routine has extra explanation for 6502 beginners.
            cmp #'9'+1
            bcs .letter         ; >'9', convert letter
            ;   At this point we know that the carry is clear, better thought
            ;   of as the borrow being set. Rather than use an extra instr
            ;   to set the carry, we instead subtract 1 from the subtrahend
            ;   because the set borrow will also be subtracted from the result.
            sbc #'0'-1          ; convert digit; if <'0', N flag set for error
            ;   Normally for an unsigned comparison we'd check to see if the
            ;   carry is clear, i.e., the borrow was used, to determine
            ;   whether our result was negative. We can't do this here to see
            ;   if our char was < '0' because of the optimization above. But
            ;   it's safe to check the N flag because we know from the check at
            ;   the start that the char was ≤ $39 ('9') and so this will
            ;   always produce a result between $39-$30=$09 and $00-$30=-$30
            ;   ($D0 in two's complement), all values of which are negative.
            ;   Since the N flag is our error code, we need not even BMI;
            ;   just let the N flag pass through.
            rts                 ; N clear, no error
.letter
            and #%11011111      ; clear bit 5 to convert to upper-case
            ;   Now the char is in one of two ranges:
            ;     $3A-$40  chars between '9' and 'A'
            ;     $40-$5F  A-Z and punctuation after ([\]^_)
            ;     $80-$FF  chars above DEL
            ;   We check the N flag here to see if the high bit is set, which
            ;   means the character is invalid. We have to do the AND first
            ;   because the N bit from the CMP test is based on the result
            ;   of the CMP subtraction.
            bmi .exit           ; high bit set, error
            ;   We subtract 'A'-$0A to bring it down to the $00-$28 range,
            ;   No SEC is needed before this SBC; we branched here because the
            ;   carry was already set and AND does not affect the carry.
            sbc #'A'-$0A
            ;   Values less than $0A are invalid, so error out on those.
            cmp #$0A            ; if <$0A, set N flag to indicate error
            ;   The result of SBC is signed, so it may be, e.g., -$01 = $FF.
            ;   However, CMP does only unsigned comparisons so the carry flag
            ;   would be set (indicating ≥) rather than clear (indicating <)
            ;   for those "negative" results. But since we know our value in A
            ;   is in range $00-$28, the most negative possible result produced
            ;   by the SBC is -$28 = $D8, so we can check the N flag instead.
            ;   Since the N flag is our error code, we need not even BMI.
.exit       rts
Curt J. Sampson - github.com/0cjs
Post Reply