【发布时间】:2017-09-17 09:15:42
【问题描述】:
我正在查看来自here 的 MOS 6502 指令集的寻址模式。
indirect, Y-indexed的描述与其他来源有点不一致。
它说
OPC ($LL),Y 操作数是有效地址加Y带进位;有效地址是零页地址处的字
但是其他消息来源没有提到带有进位位的加法。喜欢here。
计算有效地址的正确方法是什么?
【问题讨论】:
我正在查看来自here 的 MOS 6502 指令集的寻址模式。
indirect, Y-indexed的描述与其他来源有点不一致。
它说
OPC ($LL),Y 操作数是有效地址加Y带进位;有效地址是零页地址处的字
但是其他消息来源没有提到带有进位位的加法。喜欢here。
计算有效地址的正确方法是什么?
【问题讨论】:
如有疑问,最好查看官方文档。
MOS here 有一个引人入胜的原始数据表
还有 [1] 读
INDIRECT INDEXED ADDRESSING - 在间接索引寻址(称为
( Indirect) , Y)中,指令的第二个字节指向页面零中的内存位置。
这个内存位置的内容被添加到Y索引寄存器的内容中,结果是有效地址的低八位。
这个加法的进位被添加到下一页零的内容 内存位置,结果是有效地址的高八位。
所以第二次加法是通过携带进行的。
您可以将其视为Immediate(在little-endian 中)指向的16 位字与Y 寄存器零扩展为16 位的内容之间的16 位加法。
例如,如果内存和Y是
All values in hex
Address 00 01 02 03 04 ...
Value 80 02 f3 00 03 ...
Y = 90
那么(0), Y就是
low 8 bits: 80 + 90 = 10 (with carry = 1)
high 8 bits: 02 + 00 + 1 = 03
提供0310 的有效地址。同样(3), Y是
low 8 bits: 00 + 90 = 90 (with carry = 0)
high 8 bits: 03 + 00 + 0 = 03
这会产生一个值为0390 的有效地址。
您可以看到,当考虑 16 位量时,0 处的字是 0280,Y 是 0090,它们的加法如预期的那样是 0310。
长描述只是对这些事实进行编码:a)Indirect 指向的 16 位字存储在小端 b)Y 是零扩展的 c)加法是 16 位的。
在 C 中,它应该是这样的
uint16_t effective_addr(uint8_t indirect)
{
//Take the INDIRECT immediate and make a pointer to a 16-bit LE word out of it
//In C int-to-ptr is implementation define, we assume an identity map here
uint16_t* page_zero_ptr = (uint16_t*)indirect;
//The Y register is 8-bit, we consider it a 16-bit one instead
//Assume y is of unsigned type
uint16_t y_zero_ext = y;
//Do a 16-bit addition, this is equivalent to two 8-bit additions with carry
return *page_zero_ptr + y;
}
【讨论】:
rbx + \reg 指向的两个字节制作一个 big-endian 字并读取它(没有添加?)。这似乎不是 IAM 所做的。此外,这可以通过越来越多的惯用 x86-64 指令来实现。