Page 1 of 1
Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 4:51 am
by Aaendi
This past week I've been thinking a lot about designing my own CPU. I've been testing out things like 2 operand mem-reg instructions and 3 operand reg-reg instructions to see what I like best, and it occurred to me that registers are very confusing to keep tracked of. With the 65816, I've gotten used to giving every memory address a label name, so it is easy to keep track. If memory address can be labeled, could registers be labeled too?
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 5:10 am
by barrym95838
Even a relatively simple assembler should be able to equate a label with a register name, but it would still be a bit confusing in a large or complex program, because there would be an almost certain need for overlapping labels.
Here is a short SWEET-16 example, using
San Bergmans' assembler. Note the register equates starting around line #40:
Code: Select all
0000- 5 ;-----------------------------------------------------;
0000- 6 ; BEER SONG FOR THE SWEET16 PSEUDO-PROCESSOR ;
0000- 7 ; BY BARRYM 2011-05-21 ;
0000- 8 ;-----------------------------------------------------;
0000- 9 ; THANKS TO SBPROJECTS.COM FOR LOTS OF VALUABLE INFO ;
0000- 10 ; AND A VERY NICE ASSEMBLER!! ;
0000- 11 ; THE SWEET16 PROCESSOR WAS CREATED BY STEVE WOZNIAK ;
0000- 12 ; IN 1977 TO HELP HIM WRITE COMPACT (BUT SLOWER) ;
0000- 13 ; 16-BIT CODE ON HIS NEW BABY, THE APPLE II. HE ;
0000- 14 ; NEVER BUILT IT IN HARDWARE, BUT INSTEAD CREATED ;
0000- 15 ; A NIFTY LITTLE 372-BYTE INTERPRETER AND BURNED ;
0000- 16 ; IT INTO THE ROM OF THE ORIGINAL INTEGER BASIC ;
0000- 17 ; APPLE II. ;
0000- 18 ; SWEET16 CODE AND 6502 CODE CAN CO-EXIST PEACEFULLY ;
0000- 19 ; IN AN APPLE II MACHINE LANGUAGE PROGRAM; A 6502 ;
0000- 20 ; 'JSR $F689' IMMEDIATELY PRECEDES A BLOCK OF IN- ;
0000- 21 ; LINE SWEET16 INSTRUCTIONS AND A SWEET16 'RTN' ;
0000- 22 ; SWITCHES BACK TO 6502 MODE, WHICH MUST BE DONE ;
0000- 23 ; AT OR BEFORE PROGRAM COMPLETION. THE ORIGINAL ;
0000- 24 ; APPLE II HAD AN UPPER-CASE 40-COLUMN DISPLAY AS ;
0000- 25 ; STANDARD EQUIPMENT, SO THE OFFICIAL SONG LYRICS ;
0000- 26 ; ARE ADJUSTED ACCORDINGLY. ;
0000- 27 ; NOTE: 'ADD' AND 'SUB' ARE BUILT-IN 6502 MACROS IN ;
0000- 28 ; THE CURRENT VERSION OF THIS ASSEMBLER AND WILL ;
0000- 29 ; NOT ASSEMBLE TO THE CORRECT SWEET16 OPCODES (USE ;
0000- 30 ; '.DA #$AX' FOR 'ADD X' & '.DA #$BX' FOR 'SUB X') ;
0000- 31 ;-----------------------------------------------------;
0000- 32 ; CONSTANT EQUATES ;
0000- 33 ;-----------------------------------------------------;
F689- 34 SWEET16 = $F689 ROM: WOZ' INTERPRETER
E51B- 35 BIN2ASC = $E51B ROM: PRINT UNSIGNED16
FDED- 36 PUTCHAR = $FDED ROM: PRINT CHARACTER
0063- 37 MAXB = 99 MUST BE IN [1..65535]
0000- 38 ;-----------------------------------------------------;
0000- 39 ; REGISTER EQUATES ;
0000- 40 ;-----------------------------------------------------;
0000- 41 ACC = $0 SWEET16 MAIN ACCUMULATOR
0001- 42 BEER = $1 BEER COUNTER
0002- 43 TYPE = $2 SUBPHRASE TYPE TEMP
0003- 44 PTR = $3 TEXT POINTER
000C- 45 STK = $C SWEET16 STACK POINTER
0000- 46 ;-----------------------------------------------------;
0000- 47 ; MAIN PROGRAM ;
0000- 48 ;-----------------------------------------------------;
0E00- 49 .OR $0E00
0E00-20 89 F6 50 MAIN JSR SWEET16 ENTER SWEET16 MODE
0E03-1C 00 01 51 SET STK,$0100 INIT SWEET16 STACK POINTER
0E06-11 63 00 52 SET BEER,MAXB BEER = MAXB
0E09-B0 53 .DA #$B0 'SUB ACC' (TYPE=0)
0E0A-0C 07 54 BS PRSONG PRINT THE ENTIRE SONG
0E0C-00 55 RTN RETURN TO 6502 MODE
0E0D-60 56 RTS EXIT
0E0E- 57 ;-----------------------------------------------------;
0E0E- 58 ; PRINT ALL EXCEPT THE LAST SENTENCE ;
0E0E- 59 ;-----------------------------------------------------;
0E0E-13 5C 0E 60 BEERME SET PTR,TAKE EMIT "TAKE ONE ... IT AROUND,"
0E11-0C 12 61 BS PRBOB EMIT " ... ON THE WALL."
0E13-13 7D 0E 62 PRSONG SET PTR,CR EMIT BLANK LINE
0E16-0C 0D 63 BS PRBOB EMIT " ... ON THE WALL";
0E18-F0 64 DCR ACC TYPE = -1
0E19-13 7C 0E 65 SET PTR,COMCR EMIT ","
0E1C-0C 07 66 BS PRBOB EMIT " ... OF BEER."
0E1E-E0 67 INR ACC TYPE = +1
0E1F-F1 68 DCR BEER BEER = BEER - 1
0E20-09 EC 69 BNM1 BEERME IF BEER <> -1 THEN BEERME
0E22- 70 ;-----------------------------------------------------;
0E22- 71 ; SET UP LAST SENTENCE AND FALL THRU ;
0E22- 72 ;-----------------------------------------------------;
0E22-11 63 00 73 SET BEER,MAXB BEER = MAXB
0E25- 74 ; EMIT "GO TO ... BUY SOME MORE,"
0E25- 75 ;-----------------------------------------------------;
0E25- 76 ; PRINT A PROPERLY PUNCTUATED BOTTLE SUB-PHRASE ;
0E25- 77 ; (ENTRY): PTR CONTAINS PRE-STRING POINTER, ACC ;
0E25- 78 ; CONTAINS SUB-PHRASE TYPE (0 = " ... THE WALL", ;
0E25- 79 ; -1 = " ... OF BEER.", +1 = " ... THE WALL.") ;
0E25- 80 ; (EXIT): ACC IS CLEARED ;
0E25- 81 ;-----------------------------------------------------;
0E25-32 82 PRBOB ST TYPE
0E26-0C 25 83 BS PUTS EMIT PRE-STRING
0E28-21 84 LD BEER IF BEER = 0 THEN
0E29-06 0E 85 BZ PRBOTT EMIT "NO MORE";
0E2B-00 86 RTN IF BEER > 0 THEN
0E2C-A5 03 87 LDA $03 RETURN TO 6502 MODE JUST
0E2E-A6 02 88 LDX $02 LONG ENOUGH TO CONVERT AND
0E30-20 1B E5 89 JSR BIN2ASC EMIT BEER TO ACTIVE OUTPUT
0E33-20 8C F6 90 JSR SWEET16+3
0E36-13 86 0E 91 SET PTR,BOTTL
0E39-0C 12 92 PRBOTT BS PUTS EMIT " ... BOTTLE";
0E3B-F1 93 DCR BEER
0E3C-07 01 94 BNZ NEQ1 IF BEER = 1 THEN
0E3E-E3 95 INR PTR SKIP OVER THE "S"
0E3F-E1 96 NEQ1 INR BEER
0E40-0C 0B 97 BS PUTS EMIT " ... OF BEER";
0E42-22 98 LD TYPE
0E43-08 05 99 BM1 NOWALL IF TYPE >= 0 THEN
0E45-0C 06 100 BS PUTS EMIT " ON THE WALL";
0E47-22 101 LD TYPE
0E48-06 11 102 BZ KPUT IF TYPE <> 0 THEN
0E4A-13 A5 0E 103 NOWALL SET PTR,DOTCR EMIT "."
0E4D- 104 ;-----------------------------------------------------;
0E4D- 105 ; PRINT A NULL-TERMINATED STRING @ PTR ;
0E4D- 106 ; (ENTRY): PTR POINTS TO THE START OF THE STRING ;
0E4D- 107 ; (EXIT): PTR POINTS TO THE NEXT STRING IN MEMORY, ;
0E4D- 108 ; ACC IS CLEARED ;
0E4D- 109 ;-----------------------------------------------------;
0E4D-43 110 PUTS LD @PTR GRAB CHAR @ PTR AND ADVANCE PTR
0E4E-06 0B 111 BZ KPUT IF CHAR <> NULL THEN
0E50-00 112 RTN ESC TO 6502 MODE
0E51-A5 00 113 LDA $00 JUST LONG ENOUGH TO EMIT
0E53-20 ED FD 114 JSR PUTCHAR THE CHAR TO ACTIVE OUTPUT
0E56-20 8C F6 115 JSR SWEET16+3
0E59-01 F2 116 BR PUTS LOOP UNTIL NULL
0E5B-0B 117 KPUT RS RETURN
0E5C- 118 ;-----------------------------------------------------;
0E5C- 119 ; OPTIMIZED SONG LYRIC STRING ;
0E5C- 120 ;-----------------------------------------------------;
0E5C-D4 C1 CB C5
0E60-A0 CF CE C5
0E64-A0 C4 CF D7
0E68-CE A0 C1 CE
0E6C-C4 A0 D0 C1
0E70-D3 D3 A0 C9
0E74-D4 A0 C1 D2
0E78-CF D5 CE C4 121 TAKE .AS -"TAKE ONE DOWN AND PASS IT AROUND"
0E7C-AC 122 COMCR .AS -","
0E7D-8D 00 123 CR .AZ -#13
0E7F-CE CF A0 CD
0E83-CF D2 C5 124 .AS -"NO MORE"
0E86-A0 C2 CF D4
0E8A-D4 CC C5 00 125 BOTTL .AZ -" BOTTLE"
0E8E-D3 A0 CF C6
0E92-A0 C2 C5 C5
0E96-D2 00 126 .AZ -"S OF BEER"
0E98-A0 CF CE A0
0E9C-D4 C8 C5 A0
0EA0-D7 C1 CC CC
0EA4-00 127 .AZ -" ON THE WALL"
0EA5-AE 8D 00 128 DOTCR .AZ -".",#13
0EA8-C7 CF A0 D4
0EAC-CF A0 D4 C8
0EB0-C5 A0 D3 D4
0EB4-CF D2 C5 A0
0EB8-C1 CE C4 A0
0EBC-C2 D5 D9 A0
0EC0-D3 CF CD C5
0EC4-A0 CD CF D2
0EC8-C5 AC 8D 00 129 .AZ -"GO TO THE STORE AND BUY SOME MORE,",#13
0ECC- 130 .EN
Mike
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 7:37 am
by BigDumbDinosaur
This past week I've been thinking a lot about designing my own CPU. I've been testing out things like 2 operand mem-reg instructions and 3 operand reg-reg instructions to see what I like best, and it occurred to me that registers are very confusing to keep tracked of. With the 65816, I've gotten used to giving every memory address a label name, so it is easy to keep track. If memory address can be labeled, could registers be labeled too?
Depends on context. Are you talking about VHDL, assembly language, or what?
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 9:24 am
by Klaus2m5
For assembly: if any opcode mnemonic includes a reference to the register (INX, DEY, PHA) the answer is no. If registers are only referred to by operands, the answer is yes. For example the AVR assembler has a .DEF statement (.DEF myregister = r21).
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 6:11 pm
by Aslak3
The question could become: are registers an optimisation (or a technical compromise, if you prefer to look at it like that) or do they add instead make possible things which would be imossible without them?
I suspect the answer is the former. Ie they simplify the design and act as a sort of cache, albeit one managed by the programmer.
I'd be very surprised if there aren't real CPUs available which have no registers. But I doubt they'd have gained much real-world traction, because in the real-world optimisations (for example, against runtime speed) are important.
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 6:54 pm
by barrym95838
It's difficult for me to imagine an architecture that doesn't have at least an accumulator, instruction pointer, memory access register and memory data register, but I am willing to bet that it's possible to construct a stored-program, Turing-complete machine with less. It really boils down to whether or not a programmer is comfortable with its assembly language, and whether or not it has adequate performance for the job at hand.
CPU architectures that are not human-friendly may be compiler-friendly, or vice-versa. The favorites are usually both. I have the most fun and highest comfort-level with four to eight GP registers, but I may be in the minority here.
Mike
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 6:57 pm
by teamtempest
I suppose it would be possible create a processor whose every instruction referenced memory. So:
Code: Select all
mov absolute0,#mylabel
mov absolute1,#1000
loop:
mov (absolute0),#$00
inc absolute0
dec absolute1
bne absolute1,loop
rts
But even if there are no programmer-available register, the processor will almost certainly need some "hidden" internal registers to handle addressing, arithmetic and logic operations. The operands still have to be fetched from memory, operated on, and stored back, even if the process is invisible to the user.
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 7:17 pm
by kiamnetrem
Complete and useful CPUs can work without registers as part of the machine instructions. Once instance is the Zylin CPU core, which is a tiny 32-bit processor designed to be synthesized into FPGAs with complete support by the GCC compiler. It's stack based.
A nice overview is given here:
http://retroramblings.net/?p=434
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 8:31 pm
by ElEctric_EyE
Complete and useful CPUs can work without registers as part of the machine instructions. Once instance is the Zylin CPU core, which is a tiny 32-bit processor designed to be synthesized into FPGAs with complete support by the GCC compiler. It's stack based...
But does this make code easier to write?
Personally, I always felt limited by the 6502's X and Y registers and one accumulator. All the TYA, PLA, PHX's etc., while not a pain to follow in code, does take away from the overall machine code's speed. More registers would seem that less of the stack would be used...
One thing lacking in the 65Or16 that I would have liked for my 'take' on a better 6502, i.e. 65Org16, would have been simple SWAP opcodes to accomodate the 16 accumulators and x,y,w registers. But it does have the ability to transfer a value from any of the 16 accumulators/3 registers amongst themselves. Obviously this is not a SWAP though.
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 9:11 pm
by GARTHWILSON
Complete and useful CPUs can work without registers as part of the machine instructions. Once instance is the Zylin CPU core, which is a tiny 32-bit processor designed to be synthesized into FPGAs with complete support by the GCC compiler. It's stack based...
But does this make code easier to write?
I haven't looked into that particular one, but a stack processor's native language is basically Forth, ie, that it takes very little processing for a compiler to turn Forth into the machine language; so I would venture to say that yes, it's easier to write. These are incredible performers considering their hardware simplicity and clock speeds. The stacks are onboard though, each with its own bus, so they don't have to go out on the normal memory bus for stack access, and accesses can be done on multiple buses at the same time.
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 9:30 pm
by ElEctric_EyE
... a stack processor's native language is basically Forth, ie, that it takes very little processing for a compiler to turn Forth into the machine language; so I would venture to say that yes, it's easier to write. These are incredible performers considering their hardware simplicity and clock speeds. The stacks are onboard though, each with its own bus, so they don't have to go out on the normal memory bus for stack access, and accesses can be done on multiple buses at the same time.
Multiple stacks better than more registers? Is this because of the single cycle push/pull opcodes or the compiler?
Forgive me, I've been away from 6502 (even 65Org16) software for a few months.
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 9:36 pm
by Aaendi
I just tried coding psuedo-assembly for a CPU with 4 general purpose registers (A, B, X and Y), ARM-style shifting, and 6809-style mnemonics and so far it looks like I would be comfortable programming it.
Code: Select all
ldy {x_pixel},(x)
lda y >> 4
anda #$001f
ldb {y_pixel},(x)
andb #$01f0
ora b << 1
andy #$fe00
ora y << 1
lda {bg_map},(a)
anda #$03ff
lda {collision_data},(a)
This code is supposed to check what BG tile a pixel overlaps. It seems like enough general purpose registers to make it easier than the 65xx, but not enough to be difficult to keep track of.
Re: Do registers really make code easier to write?
Posted: Mon Sep 01, 2014 11:55 pm
by Rob Finch
Having more registers available (to a point) makes it easier to get performance from a high-level compiled language like C or C++.
It's been studied, registers vs stack vs accumulator architectures.
They added more regs (r8-r15) to the x86 arch. to improve performance for some software.
Depending on what the target application of the processor is one may want more or fewer registers.
The 6502 works great with just .A, .X. and .Y for 6502 style apps.
If one isn't planning on using a high-level language compiler then it may not make that much difference how many registers are available. I wrote most of a bootrom in assembler using only four registers. Even though more registers were available it would make little difference to performance.
I use 256 regs for my latest cpu; but I intend on using compiled languages with it.
64 bit cpu's seem to have more regs. (IA64, MMIX, ).
So the answer is: I don't think registers make code easier to write; they can just enhance performance sometimes.
Re: Do registers really make code easier to write?
Posted: Tue Sep 02, 2014 5:06 am
by GARTHWILSON
... a stack processor's native language is basically Forth, ie, that it takes very little processing for a compiler to turn Forth into the machine language; so I would venture to say that yes, it's easier to write. These are incredible performers considering their hardware simplicity and clock speeds. The stacks are onboard though, each with its own bus, so they don't have to go out on the normal memory bus for stack access, and accesses can be done on multiple buses at the same time.
Multiple stacks better than more registers? Is this because of the single cycle push/pull opcodes or the compiler?
If they're onboard and have their own buses, imagine doing an operation on a number from one of the stacks and putting the result on the other stack while at the same time fetching the next instruction, all in the same cycle. A few instructions can even be combined--by the compiler I assume--such that the Harris RTX2000 routinely did 16 Forth MIPS at 12MHz. Doing 16 Forth MIPS on a 6502 in ITC Forth would require about 1.25GHz, and the '816 would require about 500MHz.
Re: Do registers really make code easier to write?
Posted: Tue Sep 02, 2014 8:10 am
by Movax12
I use a macro that I named 'mb' (Move Byte). It can output the correct code to move a byte from one location to to another:
Code: Select all
; move from one memory location to another, use A by default:
mb foo := bar
; move using .X:
mb x, foo := bar
You can probably guess why code is output. Also, it can handle:
Code: Select all
mb a := bar ; will output 'lda bar'
mb foo := a ; 'sta foo'
In which case you could name register A and have it be useful:
Code: Select all
; ca65 .define macro:
.define baz a
mb baz := bar ; will output 'lda bar'
mb foo := baz ; 'sta foo'
But for standard 6502, I don't think naming registers can really help much.
You might be able to:
Code: Select all
.define offset x
ldx index
lda table, offset
But that might be pretty confusing over a comment.