4
\$\begingroup\$

Last year I started researching upon how computers work, so I started making one, at least on paper last month, but I ran into a serious problem that isn't getting a satisfying answer from any article or past question.

If I have an 8 bit memory, and according to some good reliable sources like Ben Eater and crash course computer science, half of the byte in memory is the opcode and the other half is the address which means 4 bit or 15 opcodes which is enough, but just 15 addresses which I think is not sufficient to cover a 32 kB EEPROM, so I wonder how am I supposed to get more than 15 addresses accessed from the computer or the instructions itself? Let's say I have an opcode 0101, and I want to refer that to the address 16, I can't because the highest I can go is 01011111, which is just doing something to highest of 15 addresses but if this is the reality, a 64 bit device should only be able to use 4 GB of RAM, but there are 16 GB also, so how can I fix this problem?

If I have a look at a MOS6502 Microprocessor, it has 16 address pins, so does it mean that it is a 16bit address register and that it is designed for working with a 64kb memory and is that why Ben Eater in his EEPROM video turned the EEPROM off using the Chip enable whenever the processor fetches beyond the 32kb range of the EEPROM.

\$\endgroup\$
10
  • 4
    \$\begingroup\$ You need more bits to define the larger memory. You could make some op-codes imply that the next byte is part of the extended address associated with the op-code. \$\endgroup\$
    – Andy aka
    Commented Sep 28, 2020 at 8:48
  • \$\begingroup\$ if i have a look at a mos6502 , it has 16 address pins , so is this related to my problem , is it sensible to have more a 16bit address register for ram instead of 8 bit , will it affect my device \$\endgroup\$ Commented Sep 28, 2020 at 8:51
  • 2
    \$\begingroup\$ Sure, it will affect your device and you may end up starting all over. \$\endgroup\$
    – Andy aka
    Commented Sep 28, 2020 at 8:54
  • \$\begingroup\$ okay , you can write your comment as your awnsere \$\endgroup\$ Commented Sep 28, 2020 at 8:57
  • 3
    \$\begingroup\$ If you look at the instruction sets for the 6502, 8085 and other 8 bit microprocessors, you will find that most instructions require 2 or 3 bytes - first byte for the opcode, and the second and third for data or address. Some one-byte instructions may use some bits in the single byte to select a register. \$\endgroup\$ Commented Sep 28, 2020 at 20:06

2 Answers 2

23
\$\begingroup\$

the half of the byte in memory is the opcode and other half is the address

Well, that's one way of doing it, but there are lots of ways of doing it.

Instructions don't have to contain the address. Instructions containing the address or operand is usually known as "immediate" mode, but there are various other addressing modes. You could have those four bits tell you which register contains the address to use, and the registers can be longer.

The 6502 has a number of different addressing modes that use its 8-bit registers, its 16-bit program counter, and immediate addresses.

Instructions don't have to be one byte (or word) long. It's certainly easier to do it this way, but you can have multi-byte instructions. X86 is notorious for this; instructions can be anything from one byte long to fifteen if you add enough prefixes and modifiers.

As you can see from the 6502 modes page, there is a "load immediate" mode which has a one byte instruction followed by two bytes defining the address to load from.

(I strongly suggest finding some good non-video sources to learn from, such as "NAND to Tetris")

\$\endgroup\$
2
  • \$\begingroup\$ Terminology: "immediate" applies when the value in the machine code is used directly as a value. Like x86 add eax, 123 (83 c0 7b add eax,0x7b) or shl eax, 4. Some people distinguish that from an address embedded in the machine code, like x86 add eax, [123456] (03 05 40 e2 01 00 add eax,DWORD PTR ds:0x1e240), calling that "direct" memory addressing. But sure, it's valid to call the 32-bit displacement in the machine code an "immediate", even though Intel x86 manuals don't (it's a disp32 vs. and imm32). \$\endgroup\$ Commented Sep 29, 2020 at 14:28
  • 1
    \$\begingroup\$ Many RISC ISAs don't have a direct addressing mode; several have only one addressing mode for loads/stores: register + immediate displacement. (e.g. MIPS is imm16(reg) with a sign-extended 16-bit displacement). For larger register widths, like 32-bit, forcing code to construct full addresses with multiple instructions (like lui for the upper half, and the lower half in a displacement as part of a load or store) is normal and keeps instruction widths fixed and small. \$\endgroup\$ Commented Sep 29, 2020 at 14:31
3
\$\begingroup\$

An approach which has used by the PIC series of microcontrollers since the 1970s is to have a pair of addresses which the PIC refers to as FSR (address 4) and INDF (address 0), but could be given other names. The FSR may be read or written like any other register, but an apparent access to INDF (i.e. an instruction whose address field is all zeroes) will use the address specified in FSR rather than the one specified in the instruction. In some processors, the FSR is 8 bits long even though the instruction address field is only 7; there's no reason the principle couldn't be applied to let a machine with a 4-byte address field access 256 bytes of RAM.

If you want to go beyond 256 bytes, you could add an FSRH register, and make accesses to address zero use address FSRH:FSR. Additionally, instead of using a single FSRH:FSR pair, you could use two of them so that e.g. an access to address 0 would use address FSR1H:FSR1, address 1 would use address FSR2H:FSR2, addresses 4 and 5 would access FSR1 and FSR1H, respectively, and addresses 6 and 7 would access FSR2 and FSR2H. To minimize the amount of circuitry required to handle the register accesses, one could implement FSR1/FSR1H/FSR2/FSR2H as write-only registers (simply use 74HC373 or equivalent), but make accesses to them also access bytes 4-7 of RAM.

\$\endgroup\$
5
  • \$\begingroup\$ that doesn't make sense to me , but yeah im getting the basic catch \$\endgroup\$ Commented Sep 29, 2020 at 2:04
  • 1
    \$\begingroup\$ In simplest form, add some logic so that any write to address 4 will, in addition to writing RAM, latch a copy of the data into an 8-bit register called FSRL, and writing address 5 will latch a copy into FSRH. Then add logic so that any time any address bits of the instruction are non-zero, they'll specify an address (with upper 12 bits all zero), but when they're all zero, the address in FSRH:FSRL will be used instead of whatever was in the isntruction. \$\endgroup\$
    – supercat
    Commented Sep 29, 2020 at 4:29
  • 2
    \$\begingroup\$ This certainly works, but it's somewhat painful to use and target compilers at. PIC16 is an interesting lesson in how to make a chip as small as possible. \$\endgroup\$
    – pjc50
    Commented Sep 29, 2020 at 14:22
  • \$\begingroup\$ @pjc50: Having such a tiny direct address space and only one FSR that can access anything outside it is painful, but if one goes with 16-bit instructions and adds a few layout-control intrinsics, a PIC-like architecture could be quite nice in many ways with a few tweaks. If I were responsible for the PIC 18, I'd have added a few ranges of about 8 bytes for FSR0+0, FSR0+1, etc., FSR1+0, FSR1+1, etc. rather than having a huge range indexed off FSR2. I'd have also added instructions "usefw" and "uselw" which would cause the indicated f register or literal constant to be used in place of W... \$\endgroup\$
    – supercat
    Commented Sep 29, 2020 at 16:08
  • \$\begingroup\$ ...for the next instruction that would use that register. Thus "usefw thing1 / addwf thing2,f" would add thing1 to thing2 without affecting w. Instead of a "bit toggle" instruction, I'd have an instruction that would change the meaning of the following instruction based upon the state of the indicated bit, so btfas bit1 / bcf bit2 would clear bit2 if bit1 was clear, but set bit2 if bit1 was set, without affecting any flags, and btfas bit1 / bsf bit2 would do the opposite. Toggling a bit without affecting flags would be two instructions: btfas bit1 / bsf bit1. \$\endgroup\$
    – supercat
    Commented Sep 29, 2020 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.