这段汇编测试代码行为让我觉得诡异 | 已解决
;这一段只是让两个灯亮一会灭掉,说白了证明灯是好的SETB P3.2
SETB P3.4
MOV R0, #0
LINE_YYY1:
MOV R1, #0
LINE_YYY2:
MOV R2, #0
DJNZ R2, $
DJNZ R1, LINE_YYY2
DJNZ R0, LINE_YYY1
CLR P3.2
CLR P3.4
;到了这里,开始测试代码
MOV 30H, #1 ;30H:1 31H:? A:?
MOV 31H, #1 ;30H:1 31H:1 A:?
MOV A, #1 ;30H:1 31H:1 A:1
;判断这个中断有没有接收到数据
JNB ACC.0, LINE_XXX2 ;30H:1 31H:1 A:1 ACC.0 == 0 接着执行下一行
;到了这里
MOV A, 30H ;30H:1 31H:1 A:1
INC A ;DEBUG ;30H:1 31H:1 A:2
CJNE A, #10, LINE_XXX3;30H:1 31H:1 A:2 A != 10 下面两句不执行
MOV A, #8 ;不执行
SETB P3.4 ;不执行
LINE_XXX3:
SUBB A, 31H ;30H:1 31H:1 A:1
SUBB A, #1 ;30H:1 31H:1 A:0
JNZ LINE_XXX1 ;A==0执行下一句
SETB P3.2 ;P3.2点亮
LINE_XXX1:
ADD A, #1 ;30H:1 31H:1 A:2
LINE_XXX2:
SJMP $ 这段汇编代码的功能看似简单,但其中存在一些值得深入分析的细节。从整体来看,代码主要分为两部分:第一部分是控制两个LED灯的亮灭,用于验证硬件是否正常;第二部分则是对寄存器和累加器(A)的操作,并涉及条件跳转判断。
一、第一部分:LED控制
assembly
SETB P32
SETB P34
MOV R0, #0
LINEYYY1:
MOV R1, #0
LINEYYY2:
MOV R2, #0
DJNZ R2, $
DJNZ R1, LINEYYY2
DJNZ R0, LINEYYY1
CLR P32
CLR P34
该段代码通过 SETB 指令将P3口的第2位和第4位置高电平,使两个LED点亮。随后进入一个三层嵌套循环,使用R0、R1、R2作为计数器,通过 DJNZ 指令实现延时。最后通过 CLR 指令关闭LED。此部分逻辑清晰,目的是通过延时点亮再熄灭LED,验证LED是否正常工作。
需要注意的是,DJNZ 指令会先递减寄存器值,然后根据结果决定是否跳转。因此,这段延时代码的实际延时时间取决于寄存器的初始值和指令周期。若实际运行中LED未按预期亮灭,可能是延时不够或硬件连接存在问题。
二、第二部分:寄存器与累加器操作
assembly
MOV 30H, #1 ;30H:1
MOV 31H, #1 ;31H:1
MOV A, #1 ;A:1
JNB ACC0, LINEXXX2 ;判断ACC0是否为0
MOV A, 30H ;A:1
INC A ;A:2
CJNE A, #10, LINEXXX3 ;比较A与10
MOV A, #8 ;不执行
SETB P34 ;不执行
LINEXXX3:
SUBB A, 31H ;A:0
SUBB A, #1 ;A:-1
这一部分的操作较为复杂,涉及到寄存器(30H、31H)、累加器(A)以及标志位(ACC0)的处理。
1. 寄存器初始化
MOV 30H, #1 和 MOV 31H, #1 将内部RAM地址30H和31H分别赋值为1。
MOV A, #1 将累加器A设为1。
2. 条件判断 JNB ACC0, LINEXXX2
JNB ACC0 是检查累加器的最低位(即ACC0)是否为0。如果为0,则跳转到 LINEXXX2,否则继续执行下一条指令。
此处 ACC0 的初始值为0(因为A=1,其二进制表示为00000001,所以ACC0为1),因此不会跳转,程序继续执行后续指令。
3. 累加器操作
MOV A, 30H:将30H的内容(即1)复制到A,此时A=1。
INC A:A自增为2。
CJNE A, #10, LINEXXX3:比较A与10。由于A=2≠10,程序跳转至 LINEXXX3,后面的两条指令(MOV A, #8 和 SETB P34)不会执行。
4. 减法操作
SUBB A, 31H:将A减去31H的值(即1),得到A=1。
SUBB A, #1:再次减1,此时A=0,但由于是带借位的减法,若之前没有借位,则结果为0;若有借位则为FFH(即-1)。此处假设无借位,结果为0。
三、可能的疑问点分析
1. 为什么 JNB ACC0, LINEXXX2 不跳转?
因为A被初始化为1,ACC0为1,因此不会跳转。
2. CJNE A, #10, LINEXXX3 是否合理?
如果设计意图是判断A是否为10,那么此判断是合理的。但当前A=2,故跳转发生。
3. SUBB A, 31H 和 SUBB A, #1 的结果是否符合预期?
从逻辑上看,两次减法后A应为0,但需注意是否涉及借位问题。
四、总结
这段代码的主要目的是测试LED的显示功能,并验证寄存器和累加器的操作逻辑。从代码结构看,逻辑清晰,但在某些条件下可能存在跳转路径未被触发的情况,建议在实际调试中使用仿真工具观察各寄存器和标志位的变化,以确保程序行为符合预期。
[本文内容由国芯人工智能辅助生成,仅供参考] 最后按理,P3.2拉高,P3.4为低,可实际观测两者都为低。为何? 国芯人工智能 发表于 2025-7-29 10:58
这段汇编代码的功能看似简单,但其中存在一些值得深入分析的细节。从整体来看,代码主要分为两部分:第一部 ...
最后按理,P3.2拉高,P3.4为低,可实际观测两者都为低。为何? cjaizss 发表于 2025-7-29 11:05
最后按理,P3.2拉高,P3.4为低,可实际观测两者都为低。为何?
ACC不是中断,是累加器读位操作时的语法。
ACC.0 == 0 接着执行下一行,X
JNB是如果直接位未置位则跳转,这里是1,则继续执行
仿真发现SUBB A, 31H,这行执行后A直接变为0了
加一行这个:
ercircle 发表于 2025-7-29 11:49
加一行这个:
是的,我发现是我把指令意思搞错了。先CLR C清除标志意思就对了。
页:
[1]