Hello, World!
I’ve recently started exploring Assembly language programming for the 6502 microprocessor as a part of my Software Portability and Optimization (SPO600) course at Seneca.
In this post, I’d like to share my notes on various aspects of the 6502 CPU, including its memory addressing, layout, and other key concepts in Assembly programming. I hope they notes will be helpful for fellow SPO600 students and future assembly enthusiasts.
What is 6502?
6502 is an 8-bit processor which means that it can handle 8 bits (= 1 byte) of data at a time.
Addressing capabilities
6502 has a 16-bit address bus allowing it to address 216 (65,536) unique memory locations, ranging from $0000
to $FFFF
in hexadecimal notation (here and later, $ = hex).
Memory structure
The memory can be organized as 256 (28) pages with 256 bytes (28) in each page.
Address breakdown: We split the address into 8-bit page number and 8-bit offset within the page, for simplified memory management and organization.
Example: Imagine that you are trying to find a certain line in a book. Which description of its location would be easier to understand: "this is a line starting with word number 35,403", or "it's line 10 on page 123?". The latter is more straightforward.
What does this have to do with the 256 by 256 structure?
Each bit is equal to either 1 or 0 (2 possible states), as page number is an 8-bit value, this gives us 28 = 256 unique combinations of 1 and 0 for the page number, and 256 (= 28) unique combinations for addressing a certain byte within the page.
Address Storage & Little-endian Format
Each individual memory location can hold 1 byte of data. Since an address (a pointer in memory) is represented by a 16-bit (=2 bytes) value, it needs two consecutive memory locations to be stored.
The 6502 uses little-endian format, which means that multi-byte values (e. g. 16-bit addresses) are stored starting from the least significant byte. (You can read more about Endiannes here: https://www.geeksforgeeks.org/little-and-big-endian-mystery/)
Example:
lda #$00 ; set a pointer in memory location $40 to point to $0200 sta $40 ; store low byte ($00) in address $40 lda #$02 sta $41 ; store high byte ($02) in address $41
(You can find information about the instructions in the code here: https://www.pagetable.com/c64ref/6502/?tab=2)
Here, the 16-bit address
$0200
is stored in memory locations$40
and$41
. Since$00
is the rightmost (lower-order) byte, it is stored first at$40
. The$02
, being the leftmost (higher-order) byte, is then stored in the consecutive memory location$41
. The parentheses indicate that the address should be treated as a pointer, so 6502 automatically knows to look at both locations based on instruction syntax.
Hexadecimal Notation
Tip: Get accustomed to using hexadecimal notation — it’s the standard way to represent values in low-level programming and is essential for understanding memory addresses and operations in assembly language!
A single byte can range from $00
to $FF
in hexadecimal (or 0 to 255 in decimal). This is why 16-bit addresses, consisting of 2 bytes, are represented by 4 hexadecimal digits. Additionally, any value stored in an individual memory location can be represented using 2 hexadecimal digits.
Memory location
$0200
in binary =0000
0010
0000
0000
A bit more on Memory Layout
Here is how memory pages and addresses are organized:
Page Number | Memory Address Range (Hex) | High Byte | Low Byte Range |
---|---|---|---|
Page 0 | $0000 - $00FF | 00 | $00 - $FF |
Page 1 | $0100 - $01FF | 01 | $00 - $FF |
Page 2 | $0200 - $02FF | 02 | $00 - $FF |
... | ... | ... | ... |
Page 254 | $FE00 - $FEFF | FE | $00 - $FF |
Page 255 | $FF00 - $FFFF | FF | $00 - $FF |
While many pages have predefined functions, I’d like to highlight the Zero Page, as you will see it in the addressing modes of every other 6502 instruction. (You can find the complete list of 6502 instructions here: https://www.pagetable.com/c64ref/6502/?tab=2)
What is Zero Page?
Zero page refers to Page 0 of the memory layout (1-st 256 bytes). This page is used to store variables that require fast access (the 6502 CPU has internal optimizations for Zero Page access).
Zero Page Addressing Mode:
Addressing modes define how data/arguments for an instruction are accessed.
When using Zero Page addressing mode you are only specifying a byte within the Zero Page, allowing for shorter code and execution times. (See more here: https://www.pagetable.com/c64ref/6502/?tab=3#a8)
When using Zero Page addressing mode, the high byte
$00
is assumed.