【发布时间】:2016-08-17 15:12:17
【问题描述】:
我正在做一个简单的程序,它在传入传输时读取 UART 缓冲区 (S0BUF),然后在我按下按钮时通过 UART 将其传回。 我正在使用 Nordic Semiconductor nRF24LE1 芯片。
我让它与 C 一起工作,当我使用 R0-R7 寄存器之一时,我让它工作。 我想要做的是使用可重定位字节而不是普通的 R 寄存器。
这是一个有效的代码。
UART_ISR: ; (Store incoming transmission in R0)
JNB RI0, UART_ISR_A
MOV R0, S0BUF
SETB P00
CLR RI0
JMP UART_ISR_END
UART_ISR_A:
SETB P01
CLR TI0
UART_ISR_END:
RETI
Main:
MOV A, P2
XRL A, #0x0FE
JZ Main_Case_A
XRL A, #(0x0FE XOR 0x0FD)
JZ Main_Case_B
...
Main_Case_A:
MOV S0BUF, R0
SJMP Main
但是,如果我进行以下更改(标有
?DT?Data segment data ; <--- THIS
rseg ?DT?Data ; <--- THIS
RX_Message: ds 1 ; <--- THIS
UART_ISR: ; (Store incoming transmission in R0)
JNB RI0, UART_ISR_A
MOV RX_Message, S0BUF ; <-- THIS
SETB P00
CLR RI0
JMP UART_ISR_END
UART_ISR_A:
SETB P01
CLR TI0
UART_ISR_END:
RETI
Main:
MOV A, P2
XRL A, #0x0FE
JZ Main_Case_A
XRL A, #(0x0FE XOR 0x0FD)
JZ Main_Case_B
...
Main_Case_A:
MOV S0BUF, RX_Message ; <--- AND THIS
SJMP Main
它组装和一切都没有警告或错误,但结果不一样。
我想要的是让汇编器/链接器决定将我的 RX_Message 字节放在内存中的哪个位置。 如果我查看列表文件,我可以看到它将它分配给地址 0x00,这对我来说很好,因为我没有在任何地方使用 R0。但我假设如果我在某处使用 R0,它会将我的 RX_Message 地址设置为 0x01(或其他).. 但那没有发生。
我错过了什么?还是我做错了?
【问题讨论】:
-
我不知道 8051,但是一个关于它如何内存映射寄存器的快速谷歌告诉我they're banked。您确定您的代码使用的是寄存器库 0 吗?如果不是,
R0不会映射到地址0x00。 -
已存入银行,我很确定我使用的是默认银行。
-
那么,修改
R0时,哪个地址会改变值?您可以使用调试器进行完整性检查,对吗?虽然,重新阅读您的问题,但我不得不猜测默认行为不会将您的数据段与寄存器组重叠。您可以使用调试器查看访问RX_Message的指令实际使用的地址吗?即弄清楚链接后发生了什么? -
你是对的,它实际上将 RX_Message 放在 mem pos 0x08
-
好吧,有些奇怪,或者至少我无法解释它.. RX_Message 放在 mem pos 0x08 到目前为止一切正常!但是程序没有按预期工作。但是,如果我跳过使用 RX_Message 标签并仅测试各种直接地址。测试 0x00 (R0), 0x07 (R7), 0x08, 0x09, 0x0A, 0x40... 0x08 和 0x09 不起作用。 0x08 和 0x09 的结果不同,但它们的行为与预期不同。我知道 SP 应该对这些地址采取行动,但我没有推送或弹出任何东西(除非它隐藏在某些指令中)。 @PeterCordes 有什么想法吗?