一直让我感到困惑的是 8 位计算机如何访问超过 256 字节的 RAM。我知道它必须使用两个寄存器,但是任何人都可以向我展示一个在汇编代码中会是什么样子的例子吗?
像:
mov a, [x] ???
一直让我感到困惑的是 8 位计算机如何访问超过 256 字节的 RAM。我知道它必须使用两个寄存器,但是任何人都可以向我展示一个在汇编代码中会是什么样子的例子吗?
像:
mov a, [x] ???
假设我们在寄存器 L 和 H 中有 LOWER 和 HIGHER 8 位地址的一半。例如,我们要从地址 32770 dec = 8002 hex 读取字节。
mov l, 02h ;lower byte of address
mov h, 80h ;higher byte of address
mov a, [hl] ;a <-- [h*256 + l]
CPU 中存在许多寻址模式。所以我们可以有一个不同的例子,例如只有一个寄存器和一个立即地址:
mov h, 80h
mov a, [2] ;a <-- [h*256 + immediate]
它始终取决于特定的 CPU 架构。例如 Zilog Z80 被称为 8 位 CPU,但它也包含许多 16 位指令。您可以像这样对其进行索引寻址:
mov ix, 8002h ;base address of an array
mov a,[ix+20] ;a <-- [ix + 20] i.e. read a byte from an array like ix[20] in C
注意: 那些旧的 8 位 CPU 使用 8 位累加器,即它们只能在 8 位寄存器中计算数学和其他算术内容,因此它们在软件计算级别上是 8 位的。而且它们的内存访问单元是8位的,即一次只能读取或写入一个字节的内存,所以它们在硬件层面上也是8位的。那些 16 位指令很慢,它们实际上是连续执行一对 8 位操作。
让我们考虑一下 8080(Z80 等),它有 8 位寄存器,但可以将寄存器配对以像 16 位寄存器一样工作。最常用的对可能是 HL,它是 H 表示地址的 8 个高位,L 表示地址的 8 个低位。其他寄存器对是 BC 和 DE——同样,大多数指令一次只使用该对中的一个寄存器,但少数可以将这对一起使用以处理 16 位数量(例如,至少在内存服务的情况下,有一个可以将 DE 添加到 HL)。
一些指令也可以直接使用 16 位地址:
jmp 01234h
6502 有点类似,但它限制了一些指令使用 RAM 的前 256 个字节(又名“页面 0”)。更高版本(65816?)确实支持选择不同的物理地址,但这些地址将被视为第 0 页。
Intel 8080 是一个 8 位 CPU,有 2 个寄存器 H 和 L 用于间接寻址,允许它寻址 16 位内存。16 位 8086 有 20 位地址和分段。80286 使用 24 位地址,高 16 位段是段描述符表的索引。32 位 x86 使用带有 PAE 的 36 位地址...
PIC微控制器在寄存器中有8位值与PC中的高位(或一些专用地址寄存器,我不记得了)合并形成13位地址(或更多,取决于架构)
微控制器(某些微处理器架构)中的另一种常见方式是bank,您可以在其中更改 CPU 每次可以看到的“内存窗口”。
For more information you can read here
6502 具有索引内存读取指令lda $01200,Y
,并且lda $1413,X
16 位地址被编码为指令的一部分。在任何时候,这种指令都会看到一个 256 字节的窗口。例如,为了访问接下来的 256 个字节,指令本身被修改为读取lda $1300,Y
。
然后 8086 具有分段架构,其中每个内存访问都与隐式或显式段寄存器耦合。mov reg,[bp]
并push/pop
与堆栈段ss相关联,[rep] movs
与 ds:[si], es:[di] 相关联;程序计数器/跳转与代码段cs相关联。
物理地址处于 8086 模式,计算方式为 stack_reg * 16 + 偏移量,尝试读取 seg_reg:[ffff] 处的字会导致段违规异常。
8086 架构中的 VGA 图形是通过将 64k 段映射到 ISA 总线的内存来实现的。此外,通过输入/输出指令对硬件进行编程,可以在图形板上选择不同的 64-k页。因此,可以将 320x200 x 256 彩色 VGA 限制提升到 640x480 SVGA。