You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:14:53