assembly 将寄存器的值以2 × 2字节的方式加载到另一个寄存器

uqzxnwby  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(215)

我正在学习Amstrad CPC的Z80汇编编程,然后我需要从两个字节的十六进制值列表中获得地址,但目前我知道如何获得1乘1字节(使用“A”寄存器)。
我有一个名为“map”的地址“表”,它存储随机的视频存储器地址。
例如:

map:
dw #C630, #C6E8, #C73D, #C78F

;;for C630 address is 4007
;;for C6e8 address is 4009
;;for C73D address is 400B
;;for C78F address is 400D

我可以访问它与索引寄存器指令(ix或iy),但当我学习更多,我明白,索引寄存器可以推和弹出或加载'A'寄存器只有1个字节,而不是2个字节,因为我需要。
我的问题是:是否有某种方法可以获取2字节地址(4007)并将完整地址(4007)加载到寄存器中,然后加载该地址的完整值(C630),而不是仅使用“A”寄存器1 × 1字节?
类似于如果存在此Z80指令:

ld hl,(ix)
6tqwzwtp

6tqwzwtp1#

你迫切需要一本Z80的程序员手册,其中包括一章详细的说明。使用你的网络搜索技巧来找到一本。
有指示做落实这一点。
例如,您可以从绝对地址读取16位值:

ld  hl,($4007)

如果你在一个寄存器对中有地址,不幸的是没有一条指令可以通过这个“指针”来读取一个16位的值。但是你可以在几条指令中完成:

ld  hl,$4007
    ; hl now has $4007

    ld  e,(hl)
    inc hl
    ld  d,(hl)

    ; optionally, if needed to restore the original address:
    dec hl

    ; alternatively, if needed to advance to the next address:
    inc hl

顺便说一句,有经验的Z80程序员尽量避免使用IX和IY,因为与HL相比,IX和IY的性能更差(多1个M1周期,多1个M2周期,每个加载操作的加法需要一些时钟,每个指令多2个字节)。例如,你可以写:

ld  l,(ix)   ; actually "ld  l,(ix+0)" that is sometimes clearer
    ld  h,(ix+1)

但这将“花费”38个时钟和6个字节,而前一个示例需要26个时钟和4个字节。
如果您需要 * 大量 * 加载,并且不需要堆栈进行处理,则可以滥用堆栈指针。我在一个Gameboy游戏中发现了这个技巧。它的处理器与Z80相当相似,但缺少像ldir这样的重复加载指令。

; don't forget to save the SP somewhere else, if necessary...
    ld  sp,$4007
    pop hl
    ;...
    ; restore the SP
k2fxgqgv

k2fxgqgv2#

我试了一下,它对我很有效:

ld hl,map
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl      ;then popped in a loop
ex de,hl
ld (hl),#ff
map:
dw #C630, #C6E8, #C73D, #C78F

相关问题