在Peter Higginson ARMLite模拟器开发秒表时遇标签位置错误求助
ARMLite秒表程序编译错误与逻辑问题修复建议
我在Peter Higginson ARMLite模拟器里开发秒表程序,一直碰到编译错误:Error Label must be first item at line 5,搞不定这个问题。我觉得开发方向大概是对的,但可能有偏差,希望能得到帮助和建议。
以下是我的汇编代码:
1| ORIGIN 0x0000 2| EXPORT start_stopwatch 3| SECTION .data 4| message 5| DCB "Seconds: " 6| DCB 0 7| SECTION .text 8| seconds RN 0 9| start_time RN 1 10| 11| _start 12| LDR R0, =seconds 13| MOV R1, #0 14| STR R1, [R0] 15| BL start_stopwatch 16| stopwatch_loop 17| BL display_seconds 18| BL wait_for_key 19| CMP R0, #'p' 20| BEQ pause_stopwatch 21| CMP R0, #'r' 22| BEQ resume_stopwatch 23| CMP R0, #'s' 24| BEQ split_time 25| BL continue_stopwatch 26| B stopwatch_loop 27|; Start the stopwatch 28| start_stopwatch 29| BL get_current_time 30| LDR R0, =start_time 31| STR R1, [R0] 32| B continue_stopwatch 33|; Continue the stopwatch 34| continue_stopwatch 35| BL get_current_time 36| LDR R0, =start_time 37| LDR R1, [R0] 38| LDR R2, =seconds 39| LDR R3, [R2] 40| SUB R3, R3, R1 41| STR R3, [R2] 42| BX LR 43|; Pause the stopwatch 44| pause_stopwatch 45| BL get_current_time 46| LDR R0, =start_time 47| STR R1, [R0] 48| B stopwatch_loop 49|; Resume the stopwatch 50| resume_stopwatch 51| BL get_current_time 52| LDR R0, =start_time 53| LDR R1, [R0] 54| LDR R2, =seconds 55| LDR R3, [R2] 56| SUB R3, R3, R1 57| STR R3, [R2] 58| BX LR 59|; Display the split time 60| split_time 61| LDR R0, =seconds 62| LDR R1, [R0] 63| BL display_seconds 64| B stopwatch_loop 65|; Get the current time 66| get_current_time 67| LDR R1, =0xFFFFFFF0 68| LDR R0, [R1] 69| BX LR 70|; Display the number of seconds 71| display_seconds 72| LDR R0, =message 73| BL put_string 74| MOV R0, R1 75| BL put_dec 76| BL put_newline 77| BX LR 78|; Wait for a key press 79| wait_for_key 80| LDR R0, =0xFFFFFFF8 81| wait_loop 82| LDR R1, [R0] 83| CMP R1, #0 84| BEQ wait_loop 85|; Output a string to the console 86| put_string 87| STR R0, [R7, #4] 88| MOV R0, #1 89| MOV R1, #0 90| SWI "PutString" 91| BX LR 92|; Output a decimal value to the console 93| put_dec 94| STR R0, [R7, #4] 95| MOV R0, #1 96| SWI "PutDec" 97| BX LR 98|; Output a newline character to the console 99| put_newline 100| LDR R0, =0x0A 101| MOV R1, #1 102| SWI "PutChar" 103| BX LR 104| END
错误修复与优化建议
1. 解决编译错误(Label must be first item at line 5)
ARMLite汇编要求所有标签必须顶格书写,不能有前置缩进。你的代码里所有标签(比如message、_start、stopwatch_loop等)前面都有空格,这会导致汇编器无法正确识别标签,进而触发错误。
修正示例:
SECTION .data message DCB "Seconds: " DCB 0 SECTION .text _start LDR R0, =seconds MOV R1, #0 ...
(标签顶格,指令可以保留缩进)
2. 修正寄存器别名与数据变量的混淆
你用seconds RN 0和start_time RN 1将寄存器R0、R1重命名,但后续代码里LDR R0, =seconds是试图加载变量地址,这完全错误——RN是寄存器别名,不是数据变量定义。
正确做法是在.data段定义实际的变量存储:
SECTION .data message DCB "Seconds: ", 0 seconds DCW 0 ; 定义16位变量存储秒数 start_time DCW 0 ; 定义变量存储基准时间 SECTION .text ; 移除 seconds RN 0 和 start_time RN 1 这两行
3. 修正秒数计算逻辑
continue_stopwatch和resume_stopwatch里的时间计算逻辑完全反转了:
- 当前逻辑:
SUB R3, R3, R1(秒数 - 基准时间),这会得到负数或无意义的值 - 正确逻辑:应该用当前时间 - 基准时间,加到已有的秒数上,再更新基准时间为当前时间,保证后续计算正确
修正后的continue_stopwatch:
continue_stopwatch BL get_current_time ; R1返回当前时间 LDR R0, =start_time LDR R2, [R0] ; R2 = 旧的基准时间 SUB R2, R1, R2 ; R2 = 当前时间 - 旧基准时间 LDR R0, =seconds LDR R3, [R0] ADD R3, R3, R2 ; 秒数 += 时间差 STR R3, [R0] STR R1, [R0, #2] ; 更新start_time为当前时间(假设seconds和start_time连续存储) BX LR
4. 完善按键输入返回逻辑
wait_for_key函数没有返回按键值,后续的CMP R0, #'p'会使用错误的寄存器值,需要在循环结束后添加返回代码:
wait_for_key LDR R0, =0xFFFFFFF8 wait_loop LDR R1, [R0] CMP R1, #0 BEQ wait_loop MOV R0, R1 ; 将按键值放入R0返回 BX LR
5. 修正SWI调用的参数错误
put_string、put_dec里的参数传递不符合ARMLite的SWI规范,比如PutString通常要求R0指向字符串,直接调用SWI即可,不需要操作R7:
put_string MOV R1, #1 SWI "PutString" BX LR put_dec MOV R1, #1 SWI "PutDec" BX LR
内容的提问来源于stack exchange,提问作者Rhys34512
相关产品推荐
相关产品推荐

