HERE :AJMP HERE 这个单片机汇编是什么意思
Créé le : 26 février 2025
Créé le : 26 février 2025
HERE :AJMP HERE
这个单片机汇编是什么意思
这是 8051 系列单片机(或与其指令系统兼容的微控制器)中的一条汇编指令。指令的含义如下:
HERE:
是一个标号(label),表示当前这条指令所在的地址被命名为 “HERE”。AJMP HERE
是一条“绝对跳转(Absolute Jump)”指令。它会无条件地跳转到标号 “HERE” 所在的地址。由于跳转的目的地和当前指令所在的地址是同一个地方,这就形成了一个死循环(无限循环)。一旦程序运行到这里,就会一直执行这条“跳回自己”的跳转指令,从而导致程序不再向下执行。
在实际应用中,像这样的死循环常用来表示程序在此停顿(等待事件)或者防止程序继续执行,甚至可以当作某种“保护”或“中止”手段。有时也会在调试过程中用来占位或观察 CPU 是否真的进入了某个特定的状态(如错误状态、异常状态等),程序员通过调试器或其他手段检测到这一点,即可确认程序跳转到了这个位置。
下面给出一个典型的 8051 汇编程序示例,并结合你的截图内容,逐行进行讲解。此程序的主要功能通常是:
注意:不同教材/代码里实际数值(如 TH0、TL0 初值)或符号名(如 IT0P、PT0M0 等)可能会略有差异,但总体逻辑相同。下面的示例与你提供的截图基本对应。
8051 的复位入口在地址 0000H
,定时器 0 的中断向量在 000BH
。常见写法如下:
assemblyORG 0000H ; 复位向量入口 RESET: AJMP MAIN ; 上电复位后跳转到主程序 MAIN ORG 000BH ; 定时器0中断向量入口 T0_VECTOR: AJMP T0P ; T0 中断触发后跳到中断服务程序 T0P
ORG 0000H
:把接下来的指令放在 0x0000 地址处。AJMP MAIN
:复位后先执行这条跳转,去主程序。ORG 000BH
:把后续指令放在 0x000B 处(即定时器 0 中断的入口)。AJMP T0P
:表示如果发生定时器 0 中断,CPU 就会跳到 T0P
这个标签执行。典型的主程序大致如下:
assemblyORG 0100H MAIN: MOV SP, #60H ; 1) 初始化堆栈指针,一般从 0x60 开始 MOV TMOD, #01H ; 2) 选择定时器 0 的模式 1(16 位定时器) ; 高 4 位控制 T1,低 4 位控制 T0 ; #01H -> T0 16 位模式,T1 未用 MOV TL0, #0CEH ; 3) 给定时器 0 低 8 位装入初值 MOV TH0, #0F0H ; 给定时器 0 高 8 位装入初值 ; 这两个值决定定时器溢出周期长短 SETB EA ; 4) 允许总中断 (Enable All interrupts) SETB ET0 ; 允许定时器 0 中断 (Enable Timer0 interrupt) SETB TR0 ; 5) 启动定时器 0 (Timer Run) HERE: AJMP HERE ; 6) 主程序在此空转或等待中断
GATE
、C/T
、M1
、M0
)控制定时器 0;#01H
表示 T0 为 16 位定时器模式(模式 1),T1 未启用。FFFFH+1
,就会触发中断。SETB EA
和 SETB ET0
:分别开启总中断和定时器 0 中断。SETB TR0
:启动定时器 0 计数。HERE: AJMP HERE
:主循环在此“原地踏步”,实际的功能依赖定时器中断去完成。在上面的向量表中,我们让定时器 0 中断跳到 T0P
。具体的中断服务程序(ISR)可以这样写:
assemblyT0P: CLR TR0 ; 1) 先关闭定时器,以免在中断服务期间继续计数 MOV TL0, #0CEH ; 2) 重新装载 T0 的初值 (低 8 位) MOV TH0, #0F0H ; 重新装载 T0 的初值 (高 8 位) ; 保证下一次溢出周期一致 SETB TR0 ; 3) 再次启动定时器 CPL P1.0 ; 4) 典型动作:翻转 P1.0 引脚,点亮/熄灭 LED 等 RETI ; 5) 中断返回
CLR TR0
/ SETB TR0
:定时器在中断过程往往需要先关后开,以确保初值装载生效。MOV TL0, #0CEH / MOV TH0, #0F0H
:跟主程序里一致,保证定时器周期恒定。CPL P1.0
:翻转一个管脚,可用来驱动 LED、输出方波等。RETI
:表示结束中断服务程序并返回主程序的无限循环处。AJMP MAIN
,跳转到主程序。SP
;TMOD
寄存器,选定时器 0 的工作模式;TH0
、TL0
写入初值(决定定时器溢出周期);EA
和定时器 0 中断 ET0
;TR0 = 1
),然后进入无限循环。AJMP T0P
。T0P
中,通常先关定时器、重装载初值、再开定时器,然后做用户需要的操作(这里是 CPL P1.0
),最后 RETI
返回主程序循环。TMOD
高 4 位设置成某种模式,再在中断入口 ORG 001BH
编写定时器 1 的中断服务。HERE: AJMP HERE
这段无限循环,改为你的业务代码,但要留意保证中断仍能正常执行。ORG ...
:指定程序各段放在相应的物理地址处(复位向量、中断向量、主程序区等)。AJMP
/ LJMP
:常用于从复位向量或中断向量跳向实际的程序/中断服务例程。TMOD
:定时器模式寄存器,决定了定时器/计数器的工作方式。TH0
/ TL0
:定时器 0 的高位与低位,写入初值后启动,以获得所需的定时/计数周期。EA
/ ET0
/ TR0
:分别为“总中断允许”“定时器 0 中断允许”“定时器 0 运行”控制位。T0P
里先关定时器、重装载初值、再开定时器,然后执行你想要在中断时完成的任务,最后 RETI
返回主程序。这样,你就能清晰地理解为什么程序中会有 HERE: AJMP HERE
这样的无限循环,以及定时器中断的意义所在。
其中的here有什么用
在这段代码中,HERE
是一个标号(label),而 AJMP HERE
则构成了一个简单的“无限循环”。它的主要作用是:
简而言之,HERE: AJMP HERE
让主程序“呆在原地”,而程序的核心逻辑则通过定时器或其他中断来完成。
为什么要这样做
在许多 8051 等微控制器的程序里,“主程序”通常只做一些初始化工作(例如设置定时器、中断、I/O 口等),然后就进入一个死循环或者说空转循环,让处理器待在这里。其原因主要有以下几点:
避免程序“跑飞”
在没有操作系统的单片机环境里,如果主程序执行完毕又没有循环,CPU 可能会继续执行存储空间里并不存在的有效指令或跳到未知区域,从而导致程序不可预料地崩溃,这在嵌入式中尤其要避免。
主循环空闲,等候中断驱动
很多单片机应用依赖中断来完成主要功能(比如定时器中断、串口中断、外部按键中断等)。一旦开启中断后,CPU 会在“空转循环”里等待,一旦有中断触发,就会立刻去执行中断服务程序(ISR)。这样主程序只在初始化和空闲时执行,到真正干活的时候,交给中断去做。
占位或“低功耗”思路
有时也会在这个无限循环里放置 NOP
或“减速指令”,甚至配合指令进入低功耗模式,然后由中断唤醒。总之,程序员通常需要一个可以“永远不结束”的循环来维持系统处于某种等待状态。
通用写法,便于扩展
如果之后需要让主程序做其他定时查询或轮询,也可以在这个循环里加上相关代码。当前示例里只是一段简洁示例,所以把它写成 HERE: AJMP HERE
这种纯空转形式。
因此,“HERE
+ AJMP HERE
” 的作用是让主程序停留在可控的位置,防止运行到未知指令区,并让系统所有的“实际业务”通过中断或其他机制来完成。