JMP 标签有效,但 JMP n 将 2 添加到 PC?

JMP label works, but JMP n adds 2 to PC?

我尝试this tutorial example使用 EdSim51 仿真器在 DAC 输出上创建斜坡:

 CLR P0.7   ; enable the DAC WR line
loop: 
 MOV P1, A  ; move data in the accumulator to the ADC inputs (on P1)
 ADD A, #8  ; increase accumulator by 8
 JMP loop   ; jump back to loop

而且效果很好。但是ROM的03H-30H是reserved for interrupts。关于这一点,我编码了

JMP 30h ; starts at address 0, 2B instruction
; reserved 03H-30H
ORG 30h

 ; same code as above
 CLR P0.7
loop:
 MOV P1, A
 ADD A, #8
 JMP loop

但这不起作用:DAC WR 线未启用。

跟着Ross Ridge的评论,我玩了一下:

使用标签按预期工作:

JMP main

ORG 30h
main:
CLR P0.7
...

但是,如果提供直接地址,似乎会跳过 CLR P0.7,这似乎是问题的根源。此代码也有效:

JMP 2Eh ; as tested, the next instruction will be at 30h
; ...
ORG 30h
CLR P0.7
...

此代码也有效

JMP 30h
; ...
ORG 30h
NOP
NOP ; 1 NOP doesn't work
CLR P0.7
...

但仍然:为什么直接地址将 PC 加 2?

JMP 指令(实际上是 SJMP 指令)是一个相对跳转,因此看起来您的汇编程序是按字面解释操作数,并使用 30h 作为编码指令中的相对偏移量操作数。由于偏移量是相对于 SJMP 指令之后的指令开始的,因此您需要跳转到地址 30h 的相对偏移量是 2Eh。如果您改用标签,则汇编器会自行计算正确的相对偏移量。