Live data from Hacker News

I believe 6502 instruction set is a good first assembly language

nemanjatrifunovic.substack.com

221–230 of 297 posts

Re: I believe 6502 instruction set is a good first assembly language

#221
post #217

I think that the first question to ask oneself is "why do you want to learn assembly language?" If you want to learn to write programs in assembly language or to debug disassembly of programs written in higher languages, then learn the language for the platform that you want to target. This also covers the "I want to write/understand retro stuff" case. If you want to understand how high-level programs are compiled in…

> why do you want to learn assembly language?

Back in the 70s I was fully aware that learning computers was the key to the universe. And if you wanted to learn how computers worked, you have to learn assembler. And if you want to be more than a beta programmer, you had to learn assembler.

> Knuth invented a hypothetical computer "MIX" with its own assembly level instruction set

I never bothered with that. Why, when real computers are available? MIX is a waste of time.

> it is not practical for many modern use cases and has sharp edges

All CPUs have their sharp edges. Like learning to use a milling machine, you don't want to drive the cutter into the vise. Sure, the 6502 doesn't have a divide instruction, but writing a divide routine is a good start to learning how to make the 6502 dance.

Re: I believe 6502 instruction set is a good first assembly language

#222
post #217

I think that the first question to ask oneself is "why do you want to learn assembly language?" If you want to learn to write programs in assembly language or to debug disassembly of programs written in higher languages, then learn the language for the platform that you want to target. This also covers the "I want to write/understand retro stuff" case. If you want to understand how high-level programs are compiled in…

I would recommend against learning MIX, and instead learn the successor, MMIX. MIX was designed in the 1960s, and as a result includes things that simply don't make sense today. For example, the number of bits in a byte is not specified. In fact, MIX is agnostic to whether or not it is a binary computer or a decimal computer! I believe for binary machines MIX says there are 6 bits in a byte, and for decimal machines there are two digits in a byte. Words are not uniform: a word consists of 5 "bytes" and a single bit, used to indicate the sign of the number. MIX has no stack manipulation instructions, and subroutines are implemented using self-modifying code. As in, in order to call a sub-routine you take your return instruction point and write it to a jump instruction in the sub-routine so it will jump back to where you want.

Re: I believe 6502 instruction set is a good first assembly language

#223

I'm slightly surprised that no one has suggested PDP-11 assembler as a good starting point if you're not going to learn a current instruction set. Perhaps it's because it was the first one I learnt properly but all the early miccroprocessors felt like a step backwards. I did spend a few years writing Z80 assembler but I wouldn't recommend it nowadays as it's not a very orthogonal instruction set and 6502 doesn't have…

The -11 instruction set is an engineering marvel. DEC had everything needed to utterly dominate the microcomputer business.

But DEC spurned that opportunity, while IBM took it over with the clumsy 8086 instruction set.

There's no purpose to learning the -11 anymore.

Re: I believe 6502 instruction set is a good first assembly language

#224
I started by reading disassembled real-mode x86 code. Not bad, not great. The thing that took me the longest to “get” was how much was implicitly coded into each instruction. Once I figured out how the accumulator worked, plus the way the flags influenced jump instructions, I found over time that most other architectures are more similar than they are different.

Re: I believe 6502 instruction set is a good first assembly language

#225

I'm slightly surprised that no one has suggested PDP-11 assembler as a good starting point if you're not going to learn a current instruction set. Perhaps it's because it was the first one I learnt properly but all the early miccroprocessors felt like a step backwards. I did spend a few years writing Z80 assembler but I wouldn't recommend it nowadays as it's not a very orthogonal instruction set and 6502 doesn't have…

Plus, learning PDP-11 ASM explains some of the idioms from C as they map directly onto the architecture! "Pointer to a pointer" is just a native addressing mode, for instance.

Yah, C's pre-increment and post-increment are map right onto the -11 addressing modes. It's a brilliantly conceived minimal instruction set. Just a joy to code in.

I rewrote EMPIRE into PDP-11 assembler.

https://github.com/DigitalMars/Empire-for-PDP-11

Re: I believe 6502 instruction set is a good first assembly language

#226

I really don't see how. When students are first exposed to computer programming, it might make sense to start with toy / compact languages that don't have any real-world use. But assembly is not the first language you're supposed to learn! It's very utilitarian and most commonly just used for debugging and reverse engineering. So why would you waste time on the assembly language of a long-obsolete platform? Plus, the…

Learning assembly is what finally made programming "click" for me. With a solid intuition for instruction sets, pointers and adressing modes I could suddenly reason about programs on another lever.

I have found good results with model of teaching since them and wish that more people tried it.

Re: I believe 6502 instruction set is a good first assembly language

#228

I really don't see how. When students are first exposed to computer programming, it might make sense to start with toy / compact languages that don't have any real-world use. But assembly is not the first language you're supposed to learn! It's very utilitarian and most commonly just used for debugging and reverse engineering. So why would you waste time on the assembly language of a long-obsolete platform? Plus, the…

With the dmd compiler, compiling with -vasm will show the generated assembly as it compiles. It's been poo-pooed because why not use objdump or -S? But once you try it, you'll know why it's so convenient, as it just emits the assembler, and not the huge pile of boilerplate needed to make an object file.

For example, I'm working on an AArch64 code generator, more specifically, generating floating point code. I have a function:

    float test(float a, float b) { return a * b; }
Compiling it with:

    dmd -c test.c -arm -vasm
yields:

    test:
    0000:   A9 BE 7B FD  stp       x29,x30,[sp,#-32]!    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldstpair_pre
    0004:   91 00 03 FD  mov       x29,sp    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#addsub_imm
    0008:   BD 00 0F A0  str       s0,[x29,#12]    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldst_pos
    000c:   B9 40 1B A0  ldr       w0,[x29,#0x18]    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldst_pos
    0010:   1E 21 08 00  fmul      s0,s0,s1    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#floatdp2
    0014:   A8 C2 7B FD  ldp       x29,x30,[sp],#0x20    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#ldstpair_post
    0018:   D6 5F 03 C0  ret    // https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#branch_reg
It emits the address, the hex instruction, the instruction mnemonic, and the URL to the instruction specification.

Yes, I know the code isn't quite correct, did I mention I was working on it? :-)

Re: I believe 6502 instruction set is a good first assembly language

#229
post #138

Earlier quoted context omitted.

It's kind of hard to get hold of a PDP-11 these days. Even getting an OS, compiler etc is not that easy. If you like the PDP-11 then you get the same qualities slightly restricted in the MSP430 and slightly enhanced in the 68000. But, really, just forget all those relics and learn either RISC-V (the best answer) or else one of the half-dozen Arm variations. I'm partial to ARM7TDMI myself for sentimental reasons doing…

> Even getting an OS, compiler etc is not that easy. There's a GCC fork [0], macro11 [1] (GCC and clang also both have macro11 backends), ack [2] and more. Getting hold of a modern compiler is trivial. > It's kind of hard to get hold of a PDP-11 these days. The PiDP-11 [3] emulator that runs on a Pi, is fairly popular among the retro crowd. So sourcing something hardware wise that behaves that way is easily possible.…

You can find original PDP-11s in the $400-$500 range?

Re: I believe 6502 instruction set is a good first assembly language

#230

Earlier quoted context omitted.

> Because it lacks many features of normal ISAs Do you have some examples of this?

The most important are the lack of integer overflow detection and indexed addressing. Integer overflow detection is required for any arithmetic operation unless it is possible to prove at compile time that overflow is impossible (which is possible mostly for operations with some counters or indices, whose values are confined inside known ranges), while indexed addressing is needed in all loops that access arrays, i.e…

> integer overflow detection

What are you looking for here? Carry and overflow flags were explicitly not included because of the additional cost for OoO processors.

Let's compare overflow detection on RISC-V vs aarch64:

    unsigned 64-bit:
        add: RV: add+bltu         Arm: adds+bcc
        sub: RV: sub+bltu         Arm: subs+bcs
        mul: RV: mulhu+mul+beqz   Arm: umulh+mul+cbz

    unsigned 32-bit:
        add: RV: addw+bgeu       Arm: adds+bcc
        sub: RV: subw+bgeu       Arm: subs+bcs
        mul: RV: mul+slli+beqz   Arm: umul+cmp lsr 32

    signed 64-bit:
        add: RV: add+slt+slti+beq    Arm: adds+bcc
        sub: RV: sub+slt+slti+beq    Arm: subs+bcs
        mul: RV: mulh+mul+srai+beq   Arm: smulh+mul+cmp asr 63

    signed 32-bit:
        add: RV: addw+add+beq     Arm: adds+bvc
        sub: RV: subw+sub+beq     Arm: subs+bvs
        mul: RV: mul+sext.w+bew   Arm: smul+asr+cmp asr 31
So it's on par for unsigned, and takes two additional independent instructions for signed 64-bit and one for signed 32-bit.

For teaching, using unsigned XLEN-bit values by default is probably a good idea anyway.

> indexed addressing

I'm not sure how much this actually matters in practice. It's nice when you access multiple arrays at the same index, such that you only need to implement one index instead of every pointer. Such loops are often vectorized, and the indexed loads become useless, once you read two values from an array index, e.g. an array of structs.

Edit: removed measurements, because I'm not sure they are correct, might add back later.

Post reply on HN