使用 .align 时 CL65 不调整地址

问题描述

我正在尝试编写一个 asm 程序,该程序使用 .align 指令来确保数据不会跨越页面边界。

然而,虽然数据在内存中的正确位置,但编译后的代码并未使用正确的地址。

根据文档 ( 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,optional = yes;
    RODATA:   load = MAIN,type = ro;
    DATA:     load = MAIN,type = rw;
    DATA256:  load = MAIN,type = rw,align = $100;
    DATA4k:   load = MAIN,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 as

   .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 表示数据对齐。

enter image description here

这在调试器中得到确认。

enter image description here

我做错了什么?或者这是链接器中的错误

解决方法

不要使用 .org 指令。配置文件设置该地址:STARTADDRESS: default = $0801.

此外,该指令告诉汇编器告诉链接器,“不要重新定位以下代码”。这会阻止 .segment 指令执行我们期望它执行的操作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...