我正在尝试编写一个使用 .align 指令来确保数据不会跨越页面边界的 asm 程序。
然而,虽然数据在内存中的正确位置,但编译后的代码并没有使用正确的地址。
根据文档(https://www.cc65.org/doc/ld65-5.html)
如果请求对齐,链接器将向输出文件添加足够的空间,以便新段从可被给定数字整除的地址开始,没有余数。所有地址都会相应调整。为了填充未使用的空间,使用零字节,或者,如果内存区域具有“fillval”属性,则使用该值。
它的这种调整似乎没有发生。
为了重现,我有以下配置文件:(注意 DATA256 段上的“对齐”)
# Assembly configuration for R38
FEATURES {
STARTADDRESS: default = $0801;
}
SYMBOLS {
__LOADADDR__: type = import;
# Putting "-u __EXEHDR__" on cl65's command line will add a BASIC RUN stub to your program.
# __EXEHDR__: type = import;
__HIMEM__: type = weak, value = $9F00;
}
MEMORY {
ZP: file = "", start = $0022, size = $0080 - $0022, define = yes;
ZP2: file = "", start = $00A9, size = $0100 - $00A9;
LOADADDR: file = %O, start = %S - 2, size = $0002;
MAIN: file = %O, start = %S, size = __HIMEM__ - %S;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP2, type = zp, optional = yes; # OK if BASIC functions not used
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
LOWCODE: load = MAIN, type = ro, optional = yes;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
DATA256: load = MAIN, type = rw, align = $100;
DATA4k: load = MAIN, type = rw, align = $1000;
BSS: load = MAIN, type = bss, define = yes;
}
FEATURES {
CONDES: type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__,
segment = ONCE;
CONDES: type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__,
segment = RODATA;
CONDES: type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__,
segment = RODATA,
import = __CALLIRQ__;
}
用 asm 作为
.org $0801 ; Assembled code should start at $0801
; (where BASIC programs start)
; The real program starts at $0810 = 2064
; 10 SYS 2064
.byte $0C, $08 ; $080C - pointer to next line of BASIC code
.byte $0A, $00 ; 2-byte line number ($000A = 10)
.byte $9E ; SYS BASIC token
.byte $20 ; [space]
.byte $32, $30, $36, $34 ; $32="2",$30="0",$36="6",$34="4"
.byte $00 ; End of Line
.byte $00, $00 ; This is address $080C containing
; 2-byte pointer to next line of BASIC code
; ($0000 = end of program)
.byte $00, $00 ; Padding so code starts at $0810
cld
stp
lda testdata
rts
.segment "DATA256"
testdata:
.byte $01, $02, $03, $04
使用以下命令行构建:
cl65 --verbose -o build.prg --cpu 65c02 -t cx16 -C asm.cfg -Ln labels.txt -m map.txt -T main.asm
这是编译的.prg。您可以看到从 $0816 读取的“lda testdata”,这不是对齐的地址。$01、$02、$03 的填充显示数据对齐。
这在调试器中得到确认。
我究竟做错了什么?或者这是链接器中的错误?